问题描述
我在拼接数组中的重复项时遇到问题 这是我所拥有的
users=[];
for(let i=0;i<30;i++) users.push({name: 'peter',number:'555'});
users.forEach((element,index,users) => {
if((element.name === 'peter') && (element.number === '555')){
users.splice(index,1);
}
});
出于某种原因,它删除了其中一些但不是全部 当我使用 for 循环时相同:/
有什么建议吗?
解决方法
您可以通过使用标准 for 循环向后迭代数组来就地删除。
const spliceWhere = (arr,predicate) => {
for (let i = arr.length - 1; i >= 0; i--) {
if (predicate(arr[i])) {
arr.splice(i,1);
}
}
return arr; // Optional,for chaining
}
const users = new Array(30).fill({ name: 'peter',number: '555' });
console.log(JSON.stringify(users));
spliceWhere(
users,({ name,number }) => name === 'peter' && number === '555'
);
console.log(JSON.stringify(users));
.as-console-wrapper { top: 0; max-height: 100% !important; }
大多数情况下的首选解决方案是使用内置方法 Array.prototype.filter
。这与 Polywhirl 的答案不同,因为它构造了一个新数组并替换了旧数组 -
let users = [
{name: 'peter',number:'555'},{name: 'alice',{name: 'peter',number:'111'},{name: 'bobby',{name: 'steve',number:'777'},number:'999'},];
users = users.filter(({ name,number }) => {
return !(name == "peter" && number == "555")
});
console.log(JSON.stringify(users));
[
{"name":"alice","number":"555"},{"name":"peter","number":"111"},{"name":"bobby",{"name":"steve","number":"777"},"number":"999"}
]
使用 De Morgan's Law,我们可以编写一个等效的逻辑表达式,与 filter
一起使用时感觉更自然 -
let users = [
{name: 'peter',number }) => {
return name != "peter" || number != "555" // <- equivalent
});
console.log(JSON.stringify(users));
// []
[
{"name":"alice","number":"999"}
]
,
根据 MDN 文档,Modifying the array during iteration
forEach() 在迭代之前不会复制数组。
例如
let a = [0,1,2,3,4,5];
a.forEach((n,I) => {
console.log(n,I);
a.shift();
});
每次调用 callback()
之前,都会获取 CURRENT I
的 a
-nd 项。并且无论I
是否改变,下次a
都会加1,直到到达CURRENT a
的末尾。
所以,你会得到:
0 0
2 1
4 2