2016-09-22 19 views
0

2つの配列が同一かどうかを調べる関数を作成していますが、現在(配列内にある可能性がある)という2つのオブジェクトが同じかどうかを確認することに固執しています。は同じです。内部for..inループ

私のコードを少し説明するために、私は、関数が終わった時に返されると、それは二番目の配列またはに存在する最初の配列の各要素に対してtrueのいずれかが含まれている必要がありeqという名前の変数を持っていますundefined要素がない場合。

また、再帰IIFEを使用して、オブジェクトにサブオブジェクトがあり、サブオブジェクトも同じかどうかを確認します。配列要素がオブジェクトリテラルであるかどうかを確認するために、私はel.constructor === Objectを使用します。

100%確実ではないが、for..inループ内で何か間違ったことをしていると思います。

コード:

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);


例1:(単純な配列のために正常に動作)

var 
    a = [1, 3, 4, 6], 
    b = [3, 1, 7, 6]; 

equals(a, b); // returns: [true, true, undefined, true] 

例2:(オブジェクトに対して動作しない)

var 
    a = [1, {a: "a", b: "b"}, 4, 6], 
    b = [{a: "a", b: "b"}, 1, 7, 6]; 

equals(a, b); /* returns: [true, undefined, undefined, true] 
       SHOULD return: [true, [true, true], undefined, true] */ 

任意の助けを大幅に高く評価されるだろう。

+0

私はすでに二つの配列を比較する関数が多数のライブラリやフレームワークの1つに存在するかなり確信しています。なぜホイールを再発明するのですか? –

+0

私の大学@HubertGrzeskowiakのための練習です:) –

+0

ああ。そして、要素の順序を無視して配列を比較したいのですか? –

答えて

0

in his answer問題がeq[index]とのいかなる接続を持っていないcにある言及しています。

コード:以下のコードに示すよう

私はそれを思い付いた迅速な解決策は、問題がc = []を削除し、それがrecに渡された時点での配列としてeq[index][i]を宣言された解決します:(ただ、生命維持)

(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

私はこの問題があなたのeq[index]がコンパレータ機能に渡されていると考えています。これは参照を渡すのではなく、単に未定義の値を渡します。関数内にc = []を設定すると、その配列を新しい配列で未定義にすることになります。 eqへの接続はありません。 eq[index]の配列をrecの外に作成し、それを(c)に渡すようにコードを再構成します。または、関数recを値に戻します。ヒューバートGrzeskowiakとして

+0

ありがとう@Hubert、あなたの答えは私に考えの良い食べ物をくれました。私は** 'eq [index] [i]' **を** rec' **に渡した時点で配列として宣言することで回避策を見つけました。 –

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));

関連する問題