Search code examples
javascriptarraysarray-reduce

Group multiple elements in array with JavaScript


I have an array

[
  { price: 10 },
  { price: 10 },
  { price: 10 },
  { price: 10 },
  { price: 20 },
  { price: 20 },
]

and I want it transformed into

[
  { numElements: 4, price: 10 },
  { numElements: 2, price: 20 },
]

I have tried using arr.reduce((prev, curr) => ..., []) to accomplish this, but I can't figure out how to do it.


Solution

  • A traditional method might use a for/loop to wrangle the data, but these days JavaScript has a number of functional methods that can help. This code uses reduce and map. To get your data in the format you want is a two stage process.

    First, use reduce to create a hash table using the price as a key (because you know the each price is going to be unique:

    const obj = arr.reduce((p, c) => {
    
      // If price exists as a key its value by 1
      // otherwise set it to 1.
      p[c.price] = ++p[c.price] || 1;
      return p;
    }, {});
    

    OUTPUT

    {
      "10": 4,
      "20": 2
    }
    

    As it stands you've got a perfectly good object that you can access by the key/price and I would probably just stop there:

    obj['10'] // 4
    

    But if you want to get that data into the format in your question, map over the object keys to return an array of new objects.

    const out = Object.keys(obj).map(key => {
      return { price: +key, numElements: obj[key] };
    });
    

    DEMO