我有一个对象数组,我需要防止将重复的对象添加到数组中。我已经尝试使用以下代码检查重复项:
const array = [{ name: 'John' }];
const newName = {
name: 'John'
};
console.log(array);
console.log(newName);
if (array.includes(newName)) {
console.log(newName.name + ' exists');
} else {
console.log('name does not exist');
}
控制台日志记录表明对象NewName与array [0]完全相同。但是,
if(array.includes(newName))
返回假。
我做错了什么?我也尝试过这篇文章中的解决方案,但没有运气:
How do I check if an array includes an object in JavaScript?
答案 0 :(得分:4)
简单来说,您可以使用array.some
Array.prototype.some() documentation。
在您自己的示例中,您可以对程序进行一些调整:
const array = [{ name: "John" }];
const newName = {
name: "John"
};
console.log(array);
console.log(newName);
if (array.some(object => object.name === newName.name)) {
console.log(newName.name + " exists");
} else {
console.log("name does not exist");
}
答案 1 :(得分:3)
如果name
是对象的标识,则可以在数组上使用some
函数:
const array = [{ name: 'John' }];
const newName = { name: 'John' };
if (array.some(({name}) => name === newName.name)) {
console.log(newName.name + ' exists');
} else {
console.log('name does not exist');
}
或者您可以检查属性计数是否相同,然后检查每个属性是否具有:
const array = [{ name: 'John', age: 33 }, { name: 'John', age: 45 }];
const newName = { age: 33, name: 'John' };
if (array.some(x => Object.keys(x).length === Object.keys(newName).length && Object.keys(x).every(p => x[p] === newName[p]))) {
console.log(newName.name + ' exists');
} else {
console.log('name does not exist');
}
答案 2 :(得分:3)
您缺少的是includes
在对象上使用时会检查身份。 newName
与数组中的对象具有相同的属性,但是它不是同一对象,只有两个名叫John的人是同一个人。例如,运行{} == {}
,您将得到false
。
要检查数组是否包含具有相同名称的对象,可以使用some
并将其传递给函数以比较该对象,例如
array.some(e => e.name == newName.name)
答案 3 :(得分:2)
使用它:
var newName = {
name: 'John'
};
console.log(array);
console.log(newName.name);
var found = array.some(obj => obj.name === newName.name);
if (found) {
console.log(newName.name + ' exists');
} else {
console.log('name does not exist');
}
答案 4 :(得分:1)
const array = [{
name: 'John'
}];
const newName = {
name: 'John'
};
let resultArr = array.filter((item) => {
return item.name === newName.name
})
let elementPresentMsg;
if (resultArr.length > 0) {
elementPresentMsg = newName.name + ' exists';
} else {
elementPresentMsg = 'name does not exist'
}
document.getElementById('msg').innerHTML = elementPresentMsg;
<html>
<body>
<p id="msg"></p>
</body>
</html>
如果要从数组中查找名称或任何其他值,如果对象的属性与对象数组中的属性相同,则以下内容应会有所帮助:
const array = [{ name: 'John' }];
const newName = {
name: 'John'
};
let resultArr = array.filter((item) => {
return item.name === newName.name
})
if (resultArr.length > 0) {
alert(newName.name + ' exists'); //any way to print result instead of alert
} else {
alert('name does not exist'); //any way to print result instead of alert
}
答案 5 :(得分:0)
这是因为您试图比较两个永远不会相等的对象的不同实例。
但是,如果通过执行JSON.stringify
将对象转换为原始字符串,则可以使用Array.includes
进行深度比较。正如 ttulka 所指出的,这仅在要搜索的对象具有与数组中要查找的对象<strong>相同顺序的属性时才有效。
const array = [{ name: 'John', age: 33 }];
const newName = {
name: 'John',
age: 33
};
if (array.map(obj => JSON.stringify(obj)).includes(JSON.stringify(newName))) {
console.log(newName.name + ' exists');
} else {
console.log('name does not exist');
}
如果查看MDN中的Array#includes
填充,您会发现使用===
严格相等运算符进行了比较:
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
// 7. Repeat, while k < len
while (k < len) {
// a. Let elementK be the result of ? Get(O, ! ToString(k)).
// b. If SameValueZero(valueToFind, elementK) is true, return true.
if (sameValueZero(o[k], valueToFind)) {
return true;
}
// c. Increase k by 1.
k++;
}
因此,当您使用===
比较两个不同的对象文字时,它们将不相等:
console.log({name :"John"} === {name :"John"});
但是另一方面,如果将原始字符串与===
进行比较,则它们是相等的:
console.log('{name:"John"}' === '{name:"John"}');
但是对于String对象却不是这样:
console.log(new String('{name:"John"}') === new String('{name:"John"}'));
答案 6 :(得分:0)
这是因为array[0]
不等于newName
。在Javascript中,它们指向不同的元素。您可以尝试console.log(array[0] == newName)
,然后获得false
。
如果要查找重复项,可以尝试如下操作:
if (JSON.stringify(array).indexOf(JSON.stringify(newName)) != -1) {
console.log('exist')
}
else {
console.log('not exist')
}