在for循环中发出问题

时间:2016-09-22 12:23:51

标签: javascript

我正在创建一个检查两个数组是否相同的函数,而我目前正在检查两个对象(可能在数组中)是否相同

为了解释一下我的代码,我有一个名为 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]

非常感谢任何帮助。

3 个答案:

答案 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;
&#13;
&#13;