Home > Mobile >  Find only the minimum Object having value Price and grouping by Category (JavaScript)
Find only the minimum Object having value Price and grouping by Category (JavaScript)

Time:12-07

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);
  • Related