web-dev-qa-db-fra.com

Underscore.js: somme des articles dans une collection

J'ai fait un petit plnkr ici pour montrer ce que j'essaie d'atteindre. J'ai un gros jeu de données, où j'aime résumer le type individuel pour obtenir un total.

Je pouvais penser à itération et à ajouter les résultats à un hachage d'objet, mais je me demande un moyen plus élégant de le résoudre avec un soulignement. J'utilise des sous-traitants.js, mais je n'ai jamais essayé la carte de réduire la carte ou d'un autre paradigme fonctionnel. Veuillez mettre à jour le PLNKR pour apprendre à faire cela.

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

 */
17
bsr
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) };
});

DÉMO

32
Sergey Berezovskiy

À peu près la même réponse que @gregl, juste avec un peu plus de soulignement:

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} })
12
Nevir

Ce qui suit fonctionnera, mais je suppose que c'est semblable à ce que vous aviez à l'esprit. L'avantage est qu'en utilisant un hachage d'objet pour stocker les totaux, vous indexez sur le type, ce qui signifie que vous n'avez pas à itération à travers le hachage chaque fois que vous essayez de trouver l'objet avec le bon type. Ensuite, vous l'avez itérale une fois à la fin pour construire la matrice de sortie finale.

Plunkr est ici .

Le code est comme suit:

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: J'ai créé une nouvelle Plunkr qui génère à quelle vitesse ceci est même pour un réseau de 1 million d'articles (avec 6 types possibles) ici . Comme vous pouvez le constater à partir de la sortie de la console, au moins dans Chrome Canary, il fonctionne dans environ 1/3 seconde.

J'ai également fait un Test JSperf pour combien il est plus rapide d'utiliser le hachage intermédiaire, et cela fonctionne environ 50% plus rapide.

5
GregL