2016-03-21 6 views
0

Sagen, ich habe eine sortierte Array von Objekten wie folgt aus:hinzufügen und kombinieren Duplikate in einem Array von Objekten mit lodash mit spezifischen Bedingungen

[ 
    {name: 'item1', quantity: 5}, 
    {name: 'item1', quantity: 8}, 
    {name: 'item2', quantity: 6}, 
    {name: 'item2', quantity: 3}, 
    {name: 'item3', quantity: 1}, 
    {name: 'item3', quantity: 1}, 
] 

Ich möchte die Werte der Elemente addieren, die quantities > 1 haben und kombinieren sie so Ich bekomme das:

[ 
    {name: 'item1', quantity: 13}, 
    {name: 'item2', quantity: 9}, 
    {name: 'item3', quantity: 1}, 
    {name: 'item3', quantity: 1}, 
] 

Gibt es eine schnelle Single oder Kette von lodash Methoden, die dies erreichen können? Ich dachte, _.map zu verwenden, aber es gibt Ihnen vorher Element nicht, also würde ich eine Variable außerhalb des Bereichs _.map verwenden müssen, um diesen Wert zu behalten. Zu sehen, ob ich das mit lodash machen kann, da ich es bereits für andere Methoden verwende und keine zusätzlichen Codezeilen schreibe.

Wenn die Extra-Bedingung nicht möglich ist, müssen alle Elemente kombiniert und hinzugefügt werden.

Antwort

3

Dies ist mein Versuch mit nur lodash:

var source = [ 
 
    {name: 'item1', quantity: 5}, 
 
    {name: 'item1', quantity: 8}, 
 
    {name: 'item2', quantity: 6}, 
 
    {name: 'item2', quantity: 3}, 
 
    {name: 'item3', quantity: 1}, 
 
    {name: 'item3', quantity: 1}, 
 
]; 
 

 
var predicate = function (e) { 
 
    return e.quantity > 1; 
 
}; 
 
var result = _.chain(source) 
 
    .filter(predicate) 
 
    .groupBy(function (e) { 
 
    return e.name; 
 
    }) 
 
    .map(function (group) { 
 
    return _.reduce(group, function (current, next) { 
 
     return { 
 
     name: next.name, 
 
     quantity: current.quantity + next.quantity 
 
     }; 
 
    }); 
 
    }) 
 
    .union(_.filter(source, function (e) { 
 
    return !predicate(e); 
 
    })) 
 
    .value(); 
 

 
document.getElementById("output").textContent = JSON.stringify(result, 0, 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.min.js"></script> 
 
<pre id="output"></pre>

Nicht sicher, ob dies der effizienteste Weg ist, da ich nicht tief bin vertraut mit lodash. Grundsätzlich ist die Idee, dies:

  1. Holen Sie sich die Elemente mit der Menge> 1
  2. Gruppe namentlich
  3. Produce Summen für jeden Namen
  4. Union mit den Elementen mit der Menge < = 1

Fiddle

0

können Sie Array.prototype.forEach() verwenden, for Schleife

var arr = [ 
 
    {name: 'item1', quantity: 5}, 
 
    {name: 'item1', quantity: 8}, 
 
    {name: 'item2', quantity: 6}, 
 
    {name: 'item2', quantity: 3}, 
 
    {name: 'item3', quantity: 1}, 
 
    {name: 'item3', quantity: 1}, 
 
]; 
 

 
var res = []; 
 

 
arr.forEach(function(item, index) { 
 
    if (res.length === 0 
 
     || !res.some(function(elem) {return elem.name === item.name}) 
 
     || item["quantity"] === 1) { 
 
    res.push(item) 
 
    } else { 
 
    for (var i = 0; i < res.length; i++) { 
 
     if (res[i]["name"] === item["name"] 
 
      && (res[i]["quantity"] !== 1 && item["quantity"] !== 1)) { 
 
     res[i]["quantity"] += item["quantity"] 
 
     } 
 
    } 
 
    } 
 
}); 
 

 
document.querySelector("pre").textContent = JSON.stringify(res, null, 2)
<pre></pre>

+0

Danke für die Antwort, ich hatte gehofft zu vermeiden, extra Zeilen Code zu schreiben, da ich bereits hatte lodash in meinem Projekt, aber ich muss diesen Weg gehen. – PGT

0

Hier ist eine reine lodash-ian Lösung :)
Es chain verwendet, reduce, toPairs, map und 1 temporäre Variable mach den Job.

items = [ 
    {name: 'item1', quantity: 5}, 
    {name: 'item1', quantity: 8}, 
    {name: 'item2', quantity: 6}, 
    {name: 'item2', quantity: 3}, 
    {name: 'item3', quantity: 1}, 
    {name: 'item3', quantity: 1} 
]; 

summary = _.chain(items).reduce(function(acc, i) { 
    if (i.quantity > 0) { 
    acc[i.name] = (acc[i.name] || 0) + i.quantity; 
    } 
    return acc; 
}, {}).toPairs().map(function(x) { 
    var tmp = {}; 
    tmp[x[0]] = x[1]; 
    return tmp; 
}).value(); 

console.log(JSON.stringify(summary)); 
// Outputs: [{"item1":13},{"item2":9},{"item3":2}] 
1

Eine andere Lösung in Javascript mit einer einzigen Schleife.

var data = [{ name: 'item1', quantity: 5 }, { name: 'item1', quantity: 8 }, { name: 'item2', quantity: 6 }, { name: 'item2', quantity: 3 }, { name: 'item3', quantity: 1 }, { name: 'item3', quantity: 1 }], 
 
    combined = function (array) { 
 
     var r = []; 
 
     array.forEach(function (a, i) { 
 
      if (a.quantity === 1) { 
 
       r.push(a); 
 
       return; 
 
      } 
 
      if (!this[a.name]) { 
 
       this[a.name] = { name: a.name, quantity: 0 }; 
 
       r.push(this[a.name]); 
 
      } 
 
      this[a.name].quantity += a.quantity; 
 
     }, {}); 
 
     return r; 
 
    }(data); 
 

 
document.write('<pre>' + JSON.stringify(combined, 0, 4) + '</pre>');