суммировать значения объектов с одинаковым именем атрибута - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть массив, заполненный объектами. В следующем примере показана структура объектов.

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}]
  }
];

Я пытаюсь перебрать все значения данных, суммировать все идентичные буквы и суммировать значения в новом массиве. Поэтому новый массив должен выглядеть так:

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

Это мой текущий подход, но я не получаю его.

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]; 
  }
}

// Отредактированный пример:

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'}]
    },
  { 
];

Значения должны быть связаны одинаковыми именами. Значения Value1 и Value2 должны быть суммированы, а Value3 всегда одинакова для каждого имени.

Таким образом, результат должен выглядеть следующим образом:

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 Ответ

0 голосов
/ 01 ноября 2018

Вы можете взять Map и собрать все значения. Позже получим массив объектов из собранных значений.

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; }

Для более сложного объекта вы можете добавить отдельные свойства после проверки типа.

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; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...