Search code examples
javascriptarraysobjectecmascript-2016ecma

How to flatten an hierarchical array of objects + sum values from childs in JS


This one gives me headache, I don't know how to achieve restructuring this array of object:

const obj = [
  {
    id: 10,
    name: "foo", // parent
    value: 20
  }, {
    id: 11,
    name: "foo - 1",  // child
    value: 2
  }, {
    id: 12,
    name: "foo - 2",  // child
    value: 4
  }, {
    id: 20,
    name: "bar",// parent
    value: 10
  }, {
    id: 21,
    name: "bar - 1", // child
    value: 8
  }
];

to this:

const desired = [
  {
    id: 10,
    name: "foo",
    value: 26 // "foo" + "foo - 1" + "foo - 2"
  }, {
    id: 20,
    name: "bar",
    value: 18 // "bar" + "bar - 1"
  }
];

I want to sum the values of the respective childs, then updating the value of the parents with the result, then deleting the childs.

The implementation should work ES6+ compliant and without libraries like lodash (or similar).


Solution

  • Use reduce in order to group by the name keyword(by applying regex), afterwards take Object.values of it get array data

    const arr = [ { id: 10, name: "foo", value: 20 }, { id: 11, name: "foo - 1", value: 2 }, { id: 12, name: "foo - 2", value: 4 }, { id: 20, name: "bar", value: 10 }, { id: 21, name: "bar - 1", value: 8 }];
    
    const result = Object.values(arr.reduce((a,e)=>{
        const name = e.name.match(/\w+/g)[0];
        // OR also you can split like e.name.split("-")[0]
        a[name] ??= {...e, name, value:0};
        a[name].value+=e.value;
        return a;
    },{}));
    
    console.log(result);