从对象数组中删除重复项并更新密钥



我有一个对象数组(购物车(,我想删除具有相同obj.idobj.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。

最新更新