我有一个对象数组(购物车(,我想删除具有相同obj.id
和obj.arr
的重复项(空数组(。然后将CCD_ 3增加1。这是原始arr:
const cart = [
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
},
{
"id": 2,
"name": "pen",
"arr": ["asa", "asd"],
"quantity": 3
},
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
},
{
"id": 3,
"name": "ball pen",
"arr": ["azx", "dcv"],
"quantity": 1
}
]
预期输出应该是这样的:
const cart = [
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 2
},
{
"id": 2,
"name": "pen",
"arr": ["asa", "asd"],
"quantity": 3
},
{
"id": 3,
"name": "ball pen",
"arr": ["azx", "dcv"],
"quantity": 1
}
]
我不知道如何在删除重复后更新object.quantity
。如果可能的话,我想保留索引最小的项目
你能帮帮我吗
谢谢
为了保持订单,我会
- 构建一个以id为键的映射和一个以对象为值的数组
- 迭代此映射并检查重复项(=数组中有多个对象(
- 检查所有重复项上的空数组字段
- 在第一次出现时增加数量并覆盖现有条目(假设所有重复项都有相同的数量,并且只应增加一个,即使有两个以上的重复项(
- 重建购物车
const cart = [{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
}, {
"id": 2,
"name": "pen",
"arr": ["asa", "asd"],
"quantity": 3
}, {
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
}, {
"id": 3,
"name": "ball pen",
"arr": ["azx", "dcv"],
"quantity": 1
}]
function removeDuplicates(cart) {
let map = new Map()
// groupBy id
cart.forEach(obj => {
let entry = map.has(obj.id)
if (entry) {
let value = map.get(obj.id)
map.set(obj.id, [...value, obj])
} else {
map.set(obj.id, [obj])
}
})
map.forEach((value, key) => {
// doubles?
if (value.length > 1) {
let allEmptyArrays = value.every(obj => obj.arr.length === 0)
if (allEmptyArrays) {
// keep only the first value
let keepValue = value[0]
// adjust quantity
keepValue.quantity++
// overwrite existing entry
map.set(key, [keepValue])
}
}
})
// rebuild cart
return Array.from(map).map(([_, value]) => value[0])
}
console.log(removeDuplicates(cart))
修改了"如何从对象数组中删除所有重复项?"中的代码?。代替filter
,我使用reduce
来查找和更新重复项目的数量
const cart = [
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
},
{
"id": 2,
"name": "pen",
"arr": ["asa", "asd"],
"quantity": 3
},
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
},
{
"id": 3,
"name": "ball pen",
"arr": ["azx", "dcv"],
"quantity": 1
}
]
function findDupUpdateQty(arr){
return arr.reduce((acc, currentVal, index, self) => {
if(index === self.findIndex((e)=> e.id === currentVal.id && e.arr.length === currentVal.arr.length)){
acc.push(currentVal)
} else {
//if there's a duplicate then update quanitity
acc[acc.findIndex((e)=> e.id === currentVal.id && e.arr.length === currentVal.arr.length)].quantity += currentVal.quantity
}
return acc
},[])
}
console.log(findDupUpdateQty(cart))
使用@Corrl的一些建议进行编辑:
const cart = [
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
},
{
"id": 2,
"name": "pen",
"arr": ["asa", "asd"],
"quantity": 3
},
{
"id": 1,
"name": "book",
"arr": [],
"quantity": 1
},
{
"id": 3,
"name": "ball pen",
"arr": ["azx", "dcv"],
"quantity": 1
}
]
function findDupUpdateQty(arr){
return arr.reduce((acc, currentVal, index, self) => { //check if both arrays are the same
let firstFoundIndex = self.findIndex((e)=> e.id === currentVal.id && JSON.stringify(e.arr) === JSON.stringify(currentVal.arr))
if(index === firstFoundIndex){
acc.push(currentVal)
} else {
self[firstFoundIndex].quantity += currentVal.quantity
}
return acc
},[])
}
console.log(findDupUpdateQty(cart))
谢谢大家
我计划在"重新选择"库的选择器(createSelector
(中使用您的一个答案。但看起来,对于所有产品,它都在递增obj.quantity
,而不仅仅是那些obj.arr
为空数组的产品
所以我做了更多的研究,并根据这篇文章更改了我的addToCartReducer
。现在所有的操作都发生在减速器内部,而不是选择器内部。每次我向购物车添加一个带有obj.arr
的空数组的产品时,它都会将其quantity
递增1。