2016-03-21 42 views
0

說我有對象的這樣一個排序的數組:添加和對象的數組與特定條件lodash結合重複

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

我要添加了具有quantities > 1項的值,並將其結合,從而我得到這個:

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

是否有一個快速的單一或lodash鏈方法可以實現這一目標?我想使用_.map,但它不會給你以前的項目,所以我不得不使用_.map範圍以外的變量來保持該值。看到我是否可以用lodash做到這一點,因爲我已經將它用於其他方法,而不是寫入額外的代碼行。

如果額外的條件是不可能的,那麼組合和添加所有項目將不得不做。

回答

3

這是隻使用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>

不知道這是最有效的方式,因爲我不深熟悉lodash。基本上,這個想法是這樣的:

  1. 通過名稱獲取與數量> 1
  2. 組中的元素
  3. 農產品總和爲每名
  4. 聯盟與數量的元素< = 1

Fiddle

0

您可以使用Array.prototype.forEach()for

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

感謝您的回答,我希望避免寫出額外的代碼行,因爲我已經我的項目中包含了lodash,但我可能不得不走這條路。 – PGT

0

這是一個純粹的lodash的伊恩解決方案:)
它採用chainreducetoPairsmap和1個臨時變量做這項工作。

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

另一個解決方案是在純循環的Javascript中使用單循環。

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>');

相關問題