我正在尝试检查对象数组是否包含对象。当数组中的对象具有相同的值且对象ID无关紧要时,我希望它返回true。这是我认为的工作方式:
let arr = [{r:0, g:1}];
let obj = {r:0, g:1}
console.log(arr.includes(obj));
但是它返回false,我需要它返回true。我是否必须使用JSON.stringify()和要搜索的对象将数组中的每个对象转换为字符串,如下所示:
let arr = [JSON.stringify({r: 0, g: 1})]
let obj = {r: 0, g: 1}
console.log(arr.includes(JSON.stringify(obj)));
还有其他更简单,更有效的方法来处理更多对象吗?
答案 0 :(得分:2)
之所以得到false
,是因为对象是通过对对象的引用进行比较的,而在那里却有2个单独的对象实例。
JSON.stringify
可能会起作用,但请记住,不能保证属性的顺序,如果顺序不相同,则属性顺序可能会失败,因为您会得到不同的字符串。
如果必须将所有属性与一个循环进行比较,则可以检查id
属性或比较多个属性以进行匹配。
如果您有权访问对象的引用,则可以使用Map
或Set
来存储和检查引用
const obj = {r:0, g:1};
const obj2 = {r:0, g:1};
const mySet = new Set();
// given the fact that you do have access to the object ref
mySet.add(obj);
const isObjInList = mySet.has(obj);
const isObj2InList = mySet.has(obj2);
console.log('is obj in list - ', isObjInList);
console.log('is obj2 in list - ', isObj2InList);
答案 1 :(得分:1)
为此,我喜欢使用Set()
,请阅读文档:
通过Set对象,您可以存储任何类型的唯一值,无论是原始值还是对象引用。
请参见以下示例:
let obj = {r:0, g:1};
const set = new Set();
set.add(obj);
console.log(set.has(obj));
希望对您有帮助!
答案 2 :(得分:1)
您可以使用JavaScript some()方法来确定JavaScript数组是否包含对象。
此方法测试数组中的至少一个元素是否通过了提供的功能实现的测试。这是一个演示其工作原理的示例:
// An array of objects
var persons = [{name: "Harry"}, {name: "Alice"}, {name: "Peter"}];
// Find if the array contains an object by comparing the property value
if(persons.some(person => person.name === "Peter")){
alert("Object found inside the array.");
} else{
alert("Object not found.");
}
请注意,如果尝试使用indexOf()
之类的persons.indexOf({name: "Harry"})
方法在数组内查找对象,它将无法正常工作(始终返回-1)。因为,两个不同的对象即使看起来相同(即具有相同的属性和值)也不相等。同样,即使两个不同的数组以相同的顺序具有相同的值,它们也不相等。
所有主流浏览器(例如Chrome,Firefox,IE(9及更高版本)等)都支持some()
方法。有关JavaScript功能的更多信息,请参见JavaScript ES6功能教程。
答案 3 :(得分:1)
JSON.stringify
将无法正常工作。
您可以将lodash (或其他替代方法)中的.some
与isEqual
结合使用。或者,您也可以自己编写它,但是要小心,情况太多了,这就是为什么我建议使用现有方法的原因。无需重新发明轮子。
let arr = [JSON.stringify({r: 0, g: 1})]
let obj = {g: 1, r: 0}
console.log(arr.includes(JSON.stringify(obj)));
let arr2 = [{r:0, g:1}];
let obj2 = {g:1, r:0};
console.log(arr2.some(item => _.isEqual(item, obj2)));
console.log(_.some(arr2, item => _.isEqual(item, obj2))); // more canonical way
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>