I have an array of objects like this:
const fruits =
[
{ id: 1, fruit: "apple", store: "store1", price: 1 }
, { id: 2, fruit: "apple", store: "store2", price: 1.25 }
, { id: 3, fruit: "banana", store: "store1", price: 0.5 }
, { id: 4, fruit: "banana", store: "store2", price: 0.75 }
, { id: 5, fruit: "Orange", store: "store3", price: 5 }
, { id: 6, fruit: "Orange", store: "store1", price: 5.1 }
, { id: 7, fruit: "Cherry", store: "store1", price: .1 }
, { id: 8, fruit: "Cherry", store: "store1", price: .6 }
, { id: 9, fruit: "", store: "store1", price: 0.5 }
]
Now, I want to group them by category in ascending order which I am able to do with the following approach:
const groupBy = (fruits.sort((a, b) => a.price - b.price)).reduce((grouped, object) => {
let x = object["fruit"]
if (!grouped[x]) {
grouped[x] = []
}
grouped[x].push(object)
return grouped
}, [])
Output of above code is as expected:-
"": [{…}]
Cherry: (2) [{…}, {…}]
Orange: (2) [{…}, {…}]
apple: (2) [{…}, {…}]
banana: (2) [{…}, {…}]
Now (issue), I only want the object that has the minimum price for that category. I tried something like the below code but the output is the same as the above code:
const groupBy = (fruits.sort((a, b) => a.price - b.price)).reduce((grouped, object) => {
let x = object["fruit"]
if (!grouped[x]) {
grouped[x] = []
}
else if (grouped[x]?.price < object?.price) {
let c = grouped[x]
return grouped[x]
}
grouped[x].push(object)
return grouped
}, [])
CodePudding user response:
Not sure why you were creating an array - it looks like what you want is an object. To find the minimum price you can use Math.min
. Note that I use some shorthand to compare:
...
grouped[x] = Math.min(grouped[x] ?? 10000, object.price)
...
Which basically says 'If there isn't a current price, use 10000'
const fruits = [{
id: 1,
fruit: "apple",
store: "store1",
price: 1
}, {
id: 2,
fruit: "apple",
store: "store2",
price: 1.25
}, {
id: 3,
fruit: "banana",
store: "store1",
price: 0.5
}, {
id: 4,
fruit: "banana",
store: "store2",
price: 0.75
}, {
id: 5,
fruit: "Orange",
store: "store3",
price: 5
}, {
id: 6,
fruit: "Orange",
store: "store1",
price: 5.1
}, {
id: 7,
fruit: "Cherry",
store: "store1",
price: .1
}, {
id: 8,
fruit: "Cherry",
store: "store1",
price: .6
}, {
id: 9,
fruit: "",
store: "store1",
price: 0.5
}
]
const groupBy = fruits.reduce((grouped, object) => {
let x = object["fruit"];
if(x.trim()=="") return grouped;
grouped[x] = Math.min(grouped[x] ?? 10000, object.price)
return grouped;
}, {})
console.log(groupBy)
CodePudding user response:
Because you are already sorting based on different items price, you can simply only push to array if (!grouped[x])
. Please see it here:
const fruits = [
{ id: 1, fruit: 'apple', store: 'store1', price: 1 },
{ id: 2, fruit: 'apple', store: 'store2', price: 1.25 },
{ id: 3, fruit: 'banana', store: 'store1', price: 0.5 },
{ id: 4, fruit: 'banana', store: 'store2', price: 0.75 },
{ id: 5, fruit: 'Orange', store: 'store3', price: 5 },
{ id: 6, fruit: 'Orange', store: 'store1', price: 5.1 },
{ id: 7, fruit: 'Cherry', store: 'store1', price: 0.1 },
{ id: 8, fruit: 'Cherry', store: 'store1', price: 0.6 },
{ id: 9, fruit: '', store: 'store1', price: 0.5 },
];
const groupBy = fruits
.sort((a, b) => a.price - b.price)
.reduce((grouped, object) => {
let x = object['fruit'];
if (!grouped[x]) {
grouped[x] = [];
grouped[x].push(object);
}
return grouped;
}, []);
console.log(groupBy);