在具有特定条件的 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 做到这一点,因为我已经将它用于其他方法,而不是编写额外的代码行。
如果无法满足额外条件,则必须合并并添加所有项目。
您可以使用 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>
这是一个纯粹的 lodash-ian 解决方案:)
它使用 chain
、reduce
、toPairs
、map
和 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}]
另一种简单的解决方案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>');
这是我仅使用 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 的元素并集
假设我有一个排序的对象数组,如下所示:
[
{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 做到这一点,因为我已经将它用于其他方法,而不是编写额外的代码行。
如果无法满足额外条件,则必须合并并添加所有项目。
您可以使用 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>
这是一个纯粹的 lodash-ian 解决方案:)
它使用 chain
、reduce
、toPairs
、map
和 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}]
另一种简单的解决方案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>');
这是我仅使用 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 的元素并集