Как сложить по элементам массива - PullRequest
0 голосов
/ 11 марта 2020

У меня есть ответ API (коммиттер проекта git), в котором участники повторяются из-за того, что у них одно и то же имя, но другой адрес электронной почты.

Пример ответа:

[
  {"id": "122334", "name": "bob", "commits":10, "email": "1@abc.com"},
  {"id": "223411","name": "frank", "commits":4, "email": "frank@whatever.com"},
  {"id": "223411","name": "bob", "commits":19, "email": "bob@aol.com"},
]

Итак, здесь я хочу получить результат, подобный следующему:

[
  {"name": "bob", "commits":29},
  {"name": "frank", "commits":4},
]

Такое ощущение, что есть необходимость как в уменьшении, так и в oop .... но, возможно, кто-то может предложить более простой способ, когда это чувствует как обычные повседневные вещи!

Я выглядел немного в подчеркивании. js, и это функция groupBy, но это ощущается как излишнее для одного использования, и я тоже не мог заставить это работать:)

Ответы [ 5 ]

4 голосов
/ 11 марта 2020

Вам не нужны дополнительные for l oop. Вы можете сделать это просто с помощью функции Array.reduce. Кроме того, я бы не стал импортировать такую ​​библиотеку, как underscore, чтобы сделать что-то, что уже возможно с собственным JavaScript. По сути, вы бы импортировали тысячи строк кода, чтобы сделать простую вещь. Не лучший подход ни к чему. Вы всегда должны избегать использования библиотеки, если вы не собираетесь использовать ее несколько частей или если нет другой опции.

Пример:

const data = [
  {"id": "122334", "name": "bob", "commits":10, "email": "1@abc.com"},
  {"id": "223411","name": "frank", "commits":4, "email": "frank@whatever.com"},
  {"id": "223411","name": "bob", "commits":19, "email": "bob@aol.com"},
];

const results = data.reduce( (acc, curr) => {
  acc[curr.name] = acc[curr.name] ? acc[curr.name] + curr.commits : curr.commits;
  return acc;  
}, {});
console.log(results);
1 голос
/ 11 марта 2020

Вы можете использовать функцию reduce для группировки и функцию Object.values для извлечения сгруппированных значений.

let arr = [  {"id": "122334", "name": "bob", "commits":10, "email": "1@abc.com"},  {"id": "223411","name": "frank", "commits":4, "email": "frank@whatever.com"},  {"id": "223411","name": "bob", "commits":19, "email": "bob@aol.com"}],
    result = Object.values(arr.reduce((a, {name, commits}) => {
      (a[name] || (a[name] = {name, commits: 0})).commits += commits;
      return a;
    }, {}));

console.log(result);
1 голос
/ 11 марта 2020

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

var data = [{ id: "122334", "name": "bob", commits: 10, email: "1@abc.com" }, { id: "223411","name": "frank", commits: 4, email: "bob@aol.com" }, { id: "223411","name": "bob", commits: 19, email: "bob@aol.com" }],
    result = Object
        .entries(data.reduce((r, { name, commits }) => {
            r[name] = (r[name] || 0) + commits;
            return r;
        }, {}))
        .map(([name, commits]) => ({ name, commits }));

console.log(result);
1 голос
/ 11 марта 2020

Вы можете использовать объекты как карту, поэтому вы можете делать следующее:

const array = [
  {"id": "122334", "name": "bob", "commits":10, "email": "1@abc.com"},
  {"id": "223411","name": "frank", "commits":4, "email": "frank@whatever.com"},
  {"id": "223411","name": "bob", "commits":19, "email": "bob@aol.com"},
]; // the response
const map = {};

for (const item of array) {
    const newCommits = item.commits;
    const oldCommits = 
        (typeof map[item.name] === 'undefined') ? 0 : map[item.name];
    map[item.name] = newCommits + oldCommits;
}

const result = [];

// Now iterate over all keys
for (const key in map) {
    result.push({name: key, commits: map[key]});
}

console.log(result);
0 голосов
/ 11 марта 2020

Попробуйте это я использовал javascript структура данных карты

  const map = new Map();
  arr.forEach(item => {
    if (map.has(item.name)) {
      const i = map.get(item.name);
      i.commits += item.commits;
      map.set(item.name, i);
    } else {
      map.set(item.name, item);
    }
  });
  console.log(Array.from(map.values()));
...