我有以下功能:
function containsObject(object, array) {
for (var i = 0; i < array.length; i++) {
if (array[i] === object) {
return i;
}
}
return false;
}
以下数组:
var array = [
{
name: 'test1',
age: 12
},
{
name: 'test2',
age: 14
}
];
我需要检查以下对象是否在数组中:
var object = {
name: 'test1',
age: 12
};
但是当我使用该函数来检查数组是否包含对象时:
console.log(containsObject(object, array));
它将返回false
,因为对象的引用不相同。从技术上讲,这些对象并不相同。
如何在不分享参考的情况下继续这样做?
答案 0 :(得分:2)
小提琴:https://jsfiddle.net/thatOneGuy/3ys6s7sy/2/
您必须使用另一个对象的每个元素检查对象的每个元素。
function containsObject(object, array) {
for (var i = 0; i < array.length; i++) {
var count = 0;
var matching = true;
for (var key in object) {
if (array[i][key] === object[key]) {
matching = true;
if (count == Object.keys(array[i]).length - 1 && matching) {
return i;
} else {
count++;
}
} else {
matching = false;
}
}
}
return false;
}
var array = [{
name: 'test2',
age: 14
}, {
name: 'test1',
age: 12
}];
var thisObject = {
name: 'test1',
age: 12
};
console.log(containsObject(thisObject, array));
我改变了数据,看它是否有效。它现在记录了我的#i;正确。如果您要比较大量数据,这将非常慢。你总是可以对两个对象进行字符串化并比较两个字符串吗?
这是该功能:
function containsObject(object, array) {
for (var i = 0; i < array.length; i++) {
for (var key in object) {
//if (array[i][key] === object[key]) {
// return i;
//}
if (JSON.stringify(array[i]) === JSON.stringify(object)) {
return i;
}
}
}
return false;
}
正如评论中所提到的,第一个不适合进行深度比较。而stringify会。我会小心对象的顺序不同。例如,如果您使用此对象:
var thisObject = {
age: 12,
name: 'test1'
};
比较一下,它不会像直接的字符串比较一样工作。
使用stringify:https://jsfiddle.net/thatOneGuy/3ys6s7sy/1/
答案 1 :(得分:0)
我最终选择了theOneGuy的解决方案,改变它以便它可以搜索数组和对象:
function containsObject(needle, haystack) {
for (var i in haystack) {
var count = 0,
matching = true;
for (var key in needle) {
if (haystack[i][key] === needle[key]) {
matching = true;
if (count == Object.keys(haystack[i]).length - 1 && matching) {
return i;
} else {
count++;
}
} else {
matching = false;
}
}
}
return false;
}
答案 2 :(得分:0)
最好通过Array.prototype.contains()
的发明来完成。所以让我们发明它。但是,我将使用我之前的发明Object.prototype.compare()
和Array.prototype.compare()
Object.prototype.compare = function(o){
var ok = Object.keys(this);
return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
Array.prototype.compare = function(a){
return this.every((e,i) => typeof a[i] === "object" ? a[i].compare(e) : a[i] === e);
};
Array.prototype.contains = function(o){
return this.some(e => typeof o === "object" ? o.compare(e) : o === e);
}
var arr = [
{
name: 'test1',
age: 12
},
{
name: 'test2',
age: 14
}
],
obj1 = {
name: 'test1',
age: 12
},
obj2 = {
name: 'test1',
age: 11
},
arr2 = [1,2,3];
document.writeln(arr.contains(obj1));
document.writeln(arr.contains(obj2));
document.writeln(arr2.contains(3));
document.writeln(arr2.contains(4));
当然,你可以修改它以获得索引或找到匹配的参考。
答案 3 :(得分:0)
使用Object.keys
和Array.sort
函数的解决方案。
我已经扩展了您的初始数组以获得更复杂的示例:
function containsObject(object, array) {
var props = Object.keys(object),
len = array.length,
props_count = props.length, inner_obj, inner_props, inArray = false;
props.sort();
while (len--) {
inner_obj = array[len];
inner_props = Object.keys(inner_obj);
inner_props.sort();
if (props_count === inner_props.length) {
while (props_count--) {
if (object[props[props_count]] !== inner_obj[inner_props[props_count]]) {
break;
}
inArray = true;
}
if (inArray) return len; // return array key which has an equal object
props_count = props.length;
}
}
return false;
}
var array = [{ name: 'test3', age: 12 }, { name: 'test2', age: 14 }, { name: 'test1', age: 12 }],
object = { name: 'test1', age: 12 };
console.log(containsObject(object, array)); // 2 - appropriate key