Underscore.js: сумма элементов в коллекции - программирование

Underscore.js: сумма элементов в коллекции

Я сделал небольшой plnkr здесь, чтобы показать, чего я пытаюсь достичь. У меня есть большой набор данных, где мне нравится суммировать индивидуальный тип, чтобы получить общее количество.

Я мог бы подумать об повторении и добавлении результатов к хешу объекта, но задаюсь вопросом более элегантным способом его решения с подчеркиванием. Я использую underscore.js, но никогда не пытался уменьшить карту или другую функциональную парадигму. Обновите plnkr, чтобы узнать, как это сделать.

http://plnkr.co/edit/B5HGxhwvWsfvOR97z7TL?p=preview

var data = [ {'type': "A", 'val':2},
  {'type': "B", 'val':3},
  {'type': "A", 'val':1},
  {'type': "C", 'val':5} ];


 _.each(data, function (elm, index) {
   console.log(elm);  
 });

 /*
 Desired output

 out = [ {'type': "A", 'total':3},
  {'type': "B", 'total':3},
  {'type': "C", 'total':5} ];

 */
4b9b3361

Ответ 1

var data = [ { type: "A", val: 2 },
             { type: "B", val: 3 },
             { type: "A", val: 1 },
             { type: "C", val: 5 } ];

var groups = _(data).groupBy('type');

var out = _(groups).map(function(g, key) {
  return { type: key, 
           val: _(g).reduce(function(m,x) { return m + x.val; }, 0) };
});

DEMO

Ответ 2

В значительной степени тот же ответ, что и @GregL, просто немного подчеркиваем:

summed_by_type = _(data).reduce(function(mem, d) {
  mem[d.type] = (mem[d.type] || 0) + d.val
  return mem
}, {})

pairs = _(summed_by_type).map(function(v,k) { return {type: k, total: v} })

Ответ 3

Следующее будет работать, но я предполагаю, что оно похоже на то, что вы имели в виду. Преимущество состоит в том, что, используя хэш-объект для хранения итогов, вы индексируете тип, который означает, что вам не нужно перебирать хэш каждый раз, пытаясь найти объект с правильным типом. Затем вы перебираете его один раз в конце, чтобы создать окончательный выходной массив.

Plunkr здесь.

Код выглядит следующим образом:

var data = [ {'type': "A", 'val':2},
  {'type': "B", 'val':3},
  {'type': "A", 'val':1},
  {'type': "C", 'val':5} ];

var totalPerType = {};
for (var i = 0, len = data.length; i < len; ++i) {
  totalPerType[data[i].type] = totalPerType[data[i].type] || 0;
  totalPerType[data[i].type] += data[i].val;
}
var out = _.map(totalPerType, function(sum, type) {
  return { 'type': type, 'total': sum };
});

 console.log('out = ', out);

EDIT: Я создал новый plunkr, который генерирует, как быстро это даже для 1 миллиона элементов массива (с 6 возможными типами) здесь. Как вы можете видеть из вывода консоли, по крайней мере в Chrome Canary, он работает примерно через 1/3 секунды.

Я также выполнил jsPerf test, насколько быстрее он использует промежуточный хеш, и он работает примерно на 50% быстрее.