使用具有特定条件的lodash添加和组合对象数组中的重复项

时间:2016-03-21 21:31:47

标签: javascript arrays node.js unique lodash

假设我有一个排序的对象数组,如下所示:

ListViewItemPresenter

我想将[ {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

是否可以实现快速单一或链接的lodash方法?我正在考虑使用[ {name: 'item1', quantity: 13}, {name: 'item2', quantity: 9}, {name: 'item3', quantity: 1}, {name: 'item3', quantity: 1}, ] ,但它并没有为您提供上一项,因此我必须使用_.map范围之外的变量来保留该值。看看我是否可以用lodash做到这一点,因为我已经将它用于其他方法,而不是编写额外的代码行。

如果无法提供额外条件,则必须进行组合和添加所有项目。

4 个答案:

答案 0 :(得分: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. 获取数量为&gt的元素; 1
  2. 按名称分组
  3. 为每个名称生成总和
  4. 与数量<= 1
  5. 的元素联合

    Fiddle

答案 1 :(得分:1)

使用单循环的普通Javascript中的另一种解决方案。

dose = data.matrix(rat.dat[1])

答案 2 :(得分:0)

您可以使用forvar 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)循环

&#13;
&#13;
<pre></pre>
&#13;
.read-less
&#13;
&#13;
&#13;

答案 3 :(得分:0)

这是一个纯粹的lodash-ian解决方案:)
它使用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}]