2

I have an array filled with objects. The following example shows the structure of the objects.

let array = [
  { 
    data: [{name:'a', value:20}, {name:'b', value:10}, {name:'c', value:5}]
  },
  { 
    data: [{name:'d', value:20}, {name:'a', value:10}, {name:'e', value:40}]
  },
  { 
    data: [{name:'b', value:30}, {name:'a', value:5}]
  }
];

I'm trying to iterate through all the data values and summarize all the identical letters and sum up there values in a new array. So the new array should look like this:

let array = [{name:'a', value:35}, {name:'b', value:40}, {name:'c', value:5}, {name:'d', value:20}, {name:'e', value:40}];

This is my current approach but I don't get it to work.

let prevData = '';
let summarizedArray = [];
for(let i = 0; i < array.length; i++) {
  for(let j = 0; j < array[i].data.length; j++) {

    if(prevData === array[i].data[j].name) {
      let summarized = {
        name: array[i].data[j].name;
        value: prevData.value + array[i].data[j].value;
      }
      summarizedArray.push(summarized);
    }

    prevData = array[i].data[j]; 
  }
}

// Edited Example:

let array = [
  { 
    data: [{name:'a', value1:20, value2:90, value3:'foo'},
           {name:'b', value1:30, value2:20, value3:'boo'}]
    },
    data: [{name:'c', value1:5, value2:10, value3:'goo'},
           {name:'a', value1:30, value2:20, value3:'foo'}]
    },
  { 
];

The values should be bundled by same names. The values of Value1 and Value2 should be added up and Value3 is always the same for each name.

So the result should look like this:

let result = [{name:'a', value1:50, value2:110, value3:'foo'},
              {name:'b', value1:30, value2:20, value3:'boo'},
              {name:'c', value1:5, value2:10, value3:'goo'}
            ];
1
  • your if statement will never be true because prevData is empty. Commented Nov 1, 2018 at 19:37

1 Answer 1

1

You could take a Map and collect all values. Later get an array of object of the collected values.

let array = [{ data: [{ name: 'a', value: 20 }, { name: 'b', value: 10 }, { name: 'c', value: 5 }] }, { data: [{ name: 'd', value: 20 }, { name: 'a', value: 10 }, { name: 'd', value: 40 }] }, { data: [{ name: 'b', value: 30 }, { name: 'a', value: 5 }] }],
    result = Array.from(
        array.reduce(
            (m, { data }) => data.reduce(
                (n, { name, value }) => n.set(name, (n.get(name) || 0) + value),
                m
            ),
            new Map
        ),
        ([name, value]) => ({ name, value }) 
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For a more convoluted object, you could take single properties to add, after a check for the type.

var array = [{ data: [{ name: 'a', value1: 20, value2: 90, value3: 'foo' }, { name: 'b', value1: 30, value2: 20, value3: 'boo' }] }, { data: [{ name: 'c', value1: 5, value2: 10, value3: 'goo' }, { name: 'a', value1: 30, value2: 20, value3: 'foo' }] }],
    result = Array.from(
        array.reduce(
            (m, { data }) => {
                data.forEach(o => {
                    var temp = m.get(o.name);
                    if (!temp) {
                        m.set(o.name, temp = {});
                    }
                    Object.entries(o).forEach(([k, v]) => {
                        if (k === 'name') return;
                        if (typeof v === 'number') {
                            temp[k] = (temp[k] || 0) + v;
                        } else {
                            temp[k] = v;
                        }
                    });
                });
                return m;
            },
            new Map
        ),
        ([name, value]) => Object.assign({ name }, value)
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

3 Comments

Is it possible to compare two value attribute at once with two maps? So every object has a name and 2 different values which both are summarized in one iteration?
do you have an example, what you mean?
I've edited the post above with an new example to describe what I mean :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.