我正在创建一个检查两个数组是否相同的函数,而我目前正在检查两个对象(可能在数组中)是否相同
为了解释一下我的代码,我有一个名为 eq
的变量,当函数结束时返回它并且它应该包含 {{1第二个数组中存在的第一个数组的每个元素; >> true
,如果元素不存在
另外,我使用递归IIFE检查对象是否有子对象,子对象也是相同的。要检查数组元素是否是对象文字,我使用 undefined
。
如果不是100%肯定,我相信我在 el.constructor === Object
循环中做错了。
代码:
for..in

示例1: (适用于简单数组)
function equals(a, b) {
return (a === b && a !== null) || (a.length === b.length && (function(a, b) {
var eq = [];
a.forEach(function(el1, index) {
b.forEach(function(el2) {
if (el1 === el2) eq[index] = true;
else if (el1.constructor === el2.constructor && el1.constructor === Object) {
/* a -> the object of the first array
* b -> the object of the second array
* c -> eq[index] then eq[index][i] provided how deep it goes */
(function rec(a, b, c) {
c = [];
var i = 0;
for (var prop in a) {
for (var attr in b) {
if (prop === attr && a[prop] === b[attr]) c[i] = true;
else if (prop === attr && a[prop].constructor === b[attr].constructor
&& a[prop].constructor === Object) {
rec(a[prop], b[attr], eq[index][i]);
}
}
i++;
}
})(el1, el2, eq[index]);
}
});
});
return /*!~eq.indexOf(undefined);*/ eq;
})(a, b));
}
/* Use */
var a = [1, {a: "a", b: "b" }, 4, 6],
b = [{a: "a", b: "b"}, 1, 7, 6];
equals(a, b);
示例2: (不适用于对象)
var
a = [1, 3, 4, 6],
b = [3, 1, 7, 6];
equals(a, b); // returns: [true, true, undefined, true]
非常感谢任何帮助。
答案 0 :(得分:2)
我认为问题在于你的eq[index]
传递给比较器功能。这不会传递引用,只是一个未定义的值。通过在函数内部设置c = []
,您将覆盖未定义的新数组。与eq
无任何关联。重新构建代码,以便在eq[index]
之外的rec
中创建数组并将其传递给(c
)。或者让函数rec
返回一个值。
答案 1 :(得分:0)
正如Hubert Grzeskowiak提到in his answer,问题在于 c
与 eq[index]
没有任何联系。
我提出的解决问题的快速解决方案是删除 c = []
,并在传递 eq[index][i]
时将其声明为数组到 rec
,如下面的代码所示:
代码: (仅限IIFE)
(function rec(a, b, c) {
var i = 0;
for (var prop in a) {
for (var attr in b) {
console.log(i)
if (prop === attr && a[prop] === b[attr]) c[i] = true;
else if (prop === attr && a[prop].constructor === b[attr].constructor &&
a[prop].constructor === Object) {
rec(a[prop], b[attr], (eq[index][i] = [])); // ← instead of eq[index][i]
}
}
i++;
}
})(eachA, eachB, eq[index]);
答案 2 :(得分:0)
以下是对此的看法。代码可以使用一些缩短,我没有过度测试,但递归似乎适用于任何深度的嵌套内容。
var
a = [1, {a: "a", b: "b"}, 4, [1,{c:5,d:[1,2]}], 6],
b = [{a: "a", b: "b"}, [1,{c:5,d:[1,2]}], 1, 4, 6];
/*
* returns 'true' if arrays are the same
*
* depends on 'checkObjects'
*/
function checkArrays(arrayA, arrayB) {
if (arrayA === arrayB) return true;
if (arrayA === null || arrayB === null) return false;
if (arrayA.length !== arrayB.length) return false;
// since the order doesn't matter we sort the arrays
arrayA.sort();
arrayB.sort();
var arrayLength = arrayA.length; // stored for performance
for (var i = 0; i<arrayLength; i++) {
// if same value we continue through the array
// else they are not the same and we can stop
if (typeof arrayA[i] === 'object' && typeof arrayB[i] === 'object') {
if (!checkObjects(arrayA[i], arrayB[i])) {
return false;
}
} else if (typeof arrayA[i] === 'array' && typeof arrayB[i] === 'array') {
if (!checkArrays(arrayA[i], arrayB[i])) {
return false;
}
} else if (arrayA[i] !== arrayB[i]) {
return false;
}
}
// if we get here the values are equal
return true;
}
/*
* returns 'true' if objects are the same
*
* depends on 'checkArrays'
*/
function checkObjects(objectA, objectB) {
if (objectA === objectB) return true;
if (Object.keys(objectA).length !== Object.keys(objectB).length) return false;
var keys = Object.keys(objectA),
numberOfKeys = keys.length; // stored for performance
for (var i=0; i<numberOfKeys; i++) {
if (!(keys[i] in objectB)) {
return false; // objects don't have the same keys
} else {
if (!(objectA[keys[i]] === objectB[keys[i]])) {
// if same key-value-pairs exist we continue through the array
// else they are not the same and we can stop
if (typeof objectA[keys[i]] === 'array' && typeof objectB[keys[i]] === 'array') {
if (!checkArrays(objectA[keys[i]], objectB[keys[i]])) {
return false;
}
} else if (typeof objectA[keys[i]] === 'object' && typeof objectB[keys[i]] === 'object') {
if (!checkObjects(objectA[keys[i]], objectB[keys[i]])) {
return false;
}
} else {
return false;
}
}
}
}
// if we get here the key-value-pairs are equal
return true;
}
console.log(checkArrays(a, b));
&#13;