从对象数组中的嵌套数组中删除重复项
Posted
技术标签:
【中文标题】从对象数组中的嵌套数组中删除重复项【英文标题】:Remove duplicates from nested array in array of objects 【发布时间】:2021-08-23 16:23:57 【问题描述】:我有这个对象数组:
const arrayOfObjects = [
id: 10,
children: [1000]
,
id: 10,
children: [2000]
,
id: 20,
children: [1000]
,
id: 20,
children: [1000, 2000]
,
id: 20,
children: [2000]
,
];
我想使用此代码删除重复项:
const arrayHashMap = arrayOfObjects.reduce((obj, item) =>
if (obj[item.id])
// obj[item.id].children.push(...item.children);
const temporaryArray = [...obj[item.id].children, ...item.children];
obj[item.id].children = [...new Set(temporaryArray)];
else
obj[item.id] =
...item
;
return obj;
, );
const result = Object.values(arrayHashMap);
在这段代码中,我注释了将值推送到数组的部分。我尝试使用“new Set”从最终数组中删除重复项,但我总是将值分配给“obj[item.id].children”。这样可以吗,还是有更好的写法?
预期结果:
[
id: 10,
children: [1000, 2000]
,
id: 20,
children: [1000, 2000]
]
谢谢
【问题讨论】:
请添加想要的结果。 @NinaScholz 我添加了预期结果。 【参考方案1】:您可以按id
分组,如果值不存在,则检查数组,然后推送该值。
const
data = [ id: 10, children: [1000] , id: 10, children: [2000] , id: 20, children: [1000] , id: 20, children: [1000, 2000] , id: 20, children: [2000] ],
result = Object.values(data.reduce((r, id, children ) =>
r[id] ??= id, children: [] ;
children.forEach(v =>
if (!r[id].children.includes(v)) r[id].children.push(v);
)
return r;
, ));
console.log(result);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
【参考方案2】:使用Array#prototype#reduce
对数组进行归约并在 children 属性上初始化一个集合,然后继续添加到集合中,最后将集合映射回数组。
const arrayOfObjects = [
id: 10,
children: [1000]
,
id: 10,
children: [2000]
,
id: 20,
children: [1000]
,
id: 20,
children: [1000, 2000]
,
id: 20,
children: [2000]
,
];
const result = Object.values(
arrayOfObjects.reduce((r, c) =>
r[c.id] = r[c.id] ||
id: c.id,
children: new Set()
;
c.children.forEach((item) => r[c.id].children.add(item));
return r;
, Object.create(null))
)
.map((x) => (
id: x.id,
children: [...x.children]
));
console.log(result);
【讨论】:
【参考方案3】:const arr = [
id: 10,
children: [1000],
,
id: 10,
children: [2000],
,
id: 20,
children: [1000],
,
id: 20,
children: [1000, 2000],
,
id: 20,
children: [2000],
,
];
let result = arr.reduce((acc, i) =>
let obj = acc.find((a) => a.id === i.id);
obj ? (obj.children = [...new Set(obj.children.concat(i.children))]): acc.push(i);
return acc;
, []);
console.log(result);
【讨论】:
【参考方案4】:你可以试试这个小提琴:https://jsfiddle.net/d0kboywv/2/
const arrayOfObjects = [
id: 10,
children: [1000]
,
id: 10,
children: [2000]
,
id: 20,
children: [1000]
,
id: 20,
children: [1000, 2000, 3000]
,
id: 20,
children: [2000, 4000]
,
];
let mappedArray = new Map(arrayOfObjects.map(o => [o.id, ] ));
for (let obj of arrayOfObjects)
let child = mappedArray.get(obj.id);
for (let [key, val] of Object.entries(obj.children))
child[key] = (child[key] || new Set).add(val);
let result = Array.from(mappedArray.entries(), ([id, child]) => (
id,
children: [...new Set(Object.entries(child).map(([k, v]) =>
[...v]
).reduce((a, b) => a.concat(b), []))].sort()
));
console.log(result);
它为我完成了这项工作!
【讨论】:
【参考方案5】:您可以临时将数据结构转换为更简单
const objectOfArray = ; 你的身份是关键,你的孩子是价值
我使用名称 initialData 来引用您的数组
const objectOfArray = ;
initialData.forEach(e =>
if (objectOfArray[e.id]
objectOfArray[e.id].push(...e.children);
else
objectOfArray[e.id] = [...e.children];
);
const result = Object.entries(objectOfArray).map(([id, children]) =>
return
id,
children: children.filter((e, i) => i === chilren.indexOf(i)),
);
【讨论】:
【参考方案6】:您还可以通过运行以下代码来实现预期的输出
makeMapping = ;
for (let obj of arrayOfObjects)
makeMapping[obj.id] = ...obj, children: [...new Set([...obj.children, ...(makeMapping[obj.id]?.children || [])])];
console.log(Object.values(makeMapping));
【讨论】:
【参考方案7】:我不知道“更好”,但也许更简洁:
const arrayOfObjects = [
id: 10,
children: [1000]
,
id: 10,
children: [2000]
,
id: 20,
children: [1000]
,
id: 20,
children: [1000, 2000]
,
id: 20,
children: [2000]
,
];
const arrayHashmap = arrayOfObjects.reduce((obj,
id,
children
) => (
...obj,
[id]:
id,
children: [...new Set([
...obj[id]?.children ?? [],
...children
])]
), )
const result = Object.values(arrayHashmap);
console.log(result)
编辑:哎呀,“整洁”按钮改变了语义。固定。
【讨论】:
以上是关于从对象数组中的嵌套数组中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章