skip to Main Content

So I have an array and I want to merge or totals it base on its name

Here is an example data:

[
{
  name: "Name1",
  amt : 100,
  tax : 10,
  total : 110
},
{
  name: "Name2",
  amt : 50,
  tax : 5,
  total : 55
},
{
  name: "Name1",
  amt : 70,
  tax : 7,
  total : 77
}
]

Is there a method or reference where I can produce an output like this?

[
{
  name: "Name1",
  amt : 170,
  tax : 17,
  total : 187
},
{
  name: "Name2",
  amt : 50,
  tax : 5,
  total : 55
}
]

2

Answers


  1. You could reduce each object into a map by the key value. For each item, loop over the keys and ignore the key param.

    Sum the incoming item[k] onto the existing[k] entry.

    Finally, return the values() of the Map and spread the iterator into a new Array object.

    const reduceBy = (data, key) =>
      [...data.reduce((map, item) => {
        const existing = map.get(item[key]) ?? { [key]: item[key] };
        for (let k in item) {
          if (k !== key) {
            existing[k] = (existing[k] ?? 0) + item[k];
          }
        }
        return map.set(item[key], existing);
      }, new Map).values()];
    
    const
      input = [
        { name: "Name1", amt: 100, tax: 10, total: 110 },
        { name: "Name2", amt:  50, tax:  5, total:  55 },
        { name: "Name1", amt:  70, tax:  7, total:  77 }
      ],
      expected = [
        { name: "Name1", amt: 170, tax: 17, total: 187 },
        { name: "Name2", amt:  50, tax:  5, total:  55 }
      ],
      actual = reduceBy(input, 'name');
    
    console.log(JSON.stringify(actual) === JSON.stringify(expected));
    .as-console-wrapper { top: 0; max-height: 100% !important; }
    Login or Signup to reply.
  2. Use Array::reduce() to construct a new array, remember items by the name in a map and them into the result array and use the map to update items with new totals:

    const result = arr.reduce((r, {name, ...item}) => {
      const found = r.map.get(name);
      if(found){
        Object.keys(item).forEach(key => found[key] += item[key]);
      } else {
        r.map.set(name, r.arr[r.arr.length] = {name, ...item});  
      }
      return r;
    }, {arr: [], map: new Map}).arr;
    
    console.log(result);
    <script>
    const arr = [
    {
      name: "Name1",
      amt : 100,
      tax : 10,
      total : 110
    },
    {
      name: "Name2",
      amt : 50,
      tax : 5,
      total : 55
    },
    {
      name: "Name1",
      amt : 70,
      tax : 7,
      total : 77
    }
    ]
    </script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search