我在React的购物车页面上工作,基本上我需要按产品名称对订单进行分组并包含数量。
所以......如果我的产品阵列如下......
const items = [
{ title: 'Test', price: 1 },
{ title: 'Test', price: 1 },
{ title: 'Another Test', price: 3 },
]
我试图得到类似......
const expected = [
{ title: 'Test', price: 1, quantity: 2 },
{ title: 'Another Test', price: 3, quantity: 1 },
]
我尝试了一些不太适合我的方法,包括使用来自下划线的groupBy,但没有快乐!
这里是一个JS小提琴,我正在弄乱:https://jsfiddle.net/rL8y3Lh4/2/
答案 0 :(得分:2)
您可以使用Map
进行分组。
var items = [{ title: 'Test', price: 1 }, { title: 'Test', price: 1 }, { title: 'Another Test', price: 3 }],
grouped = items.reduce((map => (r, a) => {
if (!map.has(a.title)) {
map.set(a.title, { title: a.title, price: a.price, quantity: 0 });
r.push(map.get(a.title));
}
map.get(a.title).quantity++;
return r;
})(new Map), []);
console.log(grouped);

.as-console-wrapper { max-height: 100% !important; top: 0; }

ES5,在哈希表上有一个闭包。
var items = [{ title: 'Test', price: 1 }, { title: 'Test', price: 1 }, { title: 'Another Test', price: 3 }],
grouped = items.reduce(function (hash) {
return function (r, a) {
if (!hash[a.title]) {
hash[a.title] = { title: a.title, price: a.price, quantity: 0 };
r.push(hash[a.title]);
}
hash[a.title].quantity++;
return r;
};
}(Object.create(null)), []);
console.log(grouped);

.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)
在普通的javascript中,您可以使用reduce()
执行此操作。
const items = [
{ title: 'Test', price: 1 },
{ title: 'Test', price: 1 },
{ title: 'Another Test', price: 3 }
]
var o = {}
var result = items.reduce(function(r, e) {
if (!o[e.title]) {
o[e.title] = e;
o[e.title].quantity = 0;
r.push(o[e.title])
}
o[e.title].quantity += 1;
return r;
}, [])
console.log(result)
如果您想保存原始数据,还可以使用forEach()
和Object.assign()
创建新对象。
const items = [
{ title: 'Test', price: 1 },
{ title: 'Test', price: 1 },
{ title: 'Another Test', price: 3 },
]
var result = []
items.forEach(function(e) {
if (!this[e.title]) {
this[e.title] = Object.assign({}, e, {quantity: 0})
result.push(this[e.title])
}
this[e.title].quantity += 1
}, {})
console.log(result)
答案 2 :(得分:1)
您可以按产品名称/标题/ ID使用字典。循环遍历每个项目,添加新条目或递增现有条目的quantity
:
const items = [
{ title: 'Test', price: 1 },
{ title: 'Test', price: 1 },
{ title: 'Another Test', price: 3 }
];
let cart = {};
items.forEach(item => {
if (cart[item.title]) {
cart[item.title].quantity++;
} else {
cart[item.title] = {price: item.price, quantity: 1};
}
});
console.log(cart);
这假设具有相同title
s的项目具有相同的price
s。
答案 3 :(得分:1)
应用Array.prototype.reduce
函数的另一个简短版本:
var items = [{ title: 'Test', price: 1 },{ title: 'Test', price: 1 },{ title: 'Another Test', price: 3 }],
expected = [];
items.reduce(function (o, a) { // grouping objects by 'title' attribute
(o[a.title])?
++o[a.title].quantity
: o[a.title] = expected[expected.push({title: a.title, price: a.price, quantity: 1}) - 1];
return o;
}, {});
console.log(expected);
答案 4 :(得分:1)
如果您可以在项目中使用lodash库,我建议使用lodash unionBy
const items = [
{ title: 'Test', price: 1 },
{ title: 'Test', price: 1 },
{ title: 'Another Test', price: 3 },
];
let items1 = _.map(items, function(o) {
o.quantity = 1;
return o;
});
result = _.unionWith(items1, function(a,b) {
if(a.title === b.title) {
b.quantity++;
return true;
}
return false;
});
console.log(result);

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
&#13;
希望这是你需要的