簡體   English   中英

在特定條件下使用lodash添加和合並對象數組中的重復項

[英]Add and combine duplicates in array of objects with lodash with specific conditions

假設我有一個排序的對象數組,如下所示:

[
  {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進行此操作,因為我已經將其用於其他方法並且沒有編寫額外的代碼行。

如果沒有額外的條件,則必須合並和添加所有項目。

這是我僅使用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的元素合並

小提琴

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

您可以使用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> 

這是一個純的lodashian解決方案:)
它使用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}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM