我有两个对象数组,我需要在两个数组之间相交以找出共同的对象,然后从其中一个键都不具有相同项目的第一个数组中删除它。
请注意,我想对第一个数组本身进行突变。
这是我的代码示例,以及我在.map
上尝试过的操作,但未获得预期的结果。
(() => {
const first = Array.from({ length: 5 }, (_, i) => ({
id: `in-${i}`,
name: "one",
age: `${i * 5}`
}));
const second = Array.from({ length: 3 }, (_, i) => ({
id: `in-${i}`,
name: "two"
}));
console.log({ first });
console.log({ second });
const sid = second.map(s => s.id);
first.map((f, i) => {
if (sid.includes(f.id)) {
console.log("✔️ included");
} else {
console.log(" not included");
first.splice(i, 1);
}
});
console.log("...now...");
console.log({ first });
console.log({ second });
})();
这不会删除第一个数组的最后一个数组元素。
预期输出:
[ { id: 'in-0', name: 'one', age: '0' },
{ id: 'in-1', name: 'one', age: '5' },
{ id: 'in-2', name: 'one', age: '10' }
] }
实际输出:
[ { id: 'in-0', name: 'one', age: '0' },
{ id: 'in-1', name: 'one', age: '5' },
{ id: 'in-2', name: 'one', age: '10' },
{ id: 'in-4', name: 'one', age: '20' } ] }
我在这里犯什么错误?请帮助。
此外,建议其他任何较短且简化的方法。我想我可以在这里使用.reduce
/ forEach,但我不知道如何。
答案 0 :(得分:3)
您可以使用.filter()
const result = first.filter(f => sid.includes(f.id) );
如果您要更改first
数组,请不要使用const
,而应将其替换为let
并像这样覆盖它:
first = first.filter(f => sid.includes(f.id));
(() => {
// replace const with let
let first = Array.from({
length: 5
}, (_, i) => ({
id: `in-${i}`,
name: "one",
age: `${i * 5}`
}));
const second = Array.from({
length: 3
}, (_, i) => ({
id: `in-${i}`,
name: "two"
}));
const sid = second.map(s => s.id);
// use .filter and overwrite the first array
first = first.filter(f => sid.includes(f.id));
console.log(first);
})();
答案 1 :(得分:2)
当您通过元素2时,您的回调将删除元素3。这是数组中的索引4,因此下一次迭代将删除元素5。因为.map()
的内幕不知道,所以跳过了元素4。您正在改变数组。
如果您不想创建一个新数组,我个人将只使用一个简单的for
循环:
for (let i = first.length; --i >= 0; ) {
if (!sid.includes(first[i].id))
first.splice(i, 1);
}
如果从头到尾循环播放,则将元素拼接起来不会使事情变得混乱。