2017-12-06 7 views
2

私はJavascriptを学習していますが、配列が同じかどうかを比較するためのSOの関数があります。しかし、2つの配列が[string1、string2] & [string2、string1]の場合、私の現在の関数はfalseを返します。基本的には、2つのポジションが交換されます。コードは次のとおりです。javascriptでの配列の比較順序は関係ありません

function _compareArrays(arr1,arr2){ 
    var result = arr1 != null && arr2 != null && arr1.length == arr2.length && arr1.every(function(element) { 
      return arr2.indexOf(element); 
     }); 
    return result ; 
} 

ただし、これらの2つの配列を同じものとして返すようにします。だから、私は.every.indexOf()に変更しました。しかし、私は疑問を持っています。カウンタがどのように増分されて、各要素に対して比較が行われているかを確認するにはどうしたらいいですか? 私は、ここで、我々はやる、C++で、のような、

for (int i = 0; i < 10; i++) 
    if (arr1[i] == arr2[i] 
     cout<<"Elements are same\n"; 

を意味し、私はカウンターをインクリメントし、明示的なi++を持っています。上記の関数ではどうなりますか?

ありがとうございます!

+1

最初のコードブロックは完全なごみです。 'indexOf'は私が今まで読んだことのある文書では引数として関数を取っていません - フラットなタイヤを持っているときに.everyを.indexOf()に変更しました、ホイールをバナナに置き換えますか? –

+0

私は配列の[浅いコピーを作成する](https://stackoverflow.com/questions/3978492/javascript-fastest-way-to-duplicate-an-array-slice-vs-for-loop)、sortそれらを使用して、あなたが言及した比較メカニズムを使用します – Phil

+0

定義した '_compareArrays'メソッドは常に-1を返します。 明示的にカウンタをインクリメントせずに 'every'メソッドを反復する方法は、itterationを自動的に行うArrayプロトタイプ上の関数です。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every – nipuna777

答えて

1

あなたの現在は、これらの問題を持っている:[1, 2, 2][1,1,2]

  1. それは、これら2つのアレイ(私はあなたが、これはこれら2に固有のものではないことを理解していることを願っています)のためにtrueを返します。この問題は、以下の私のソリューションで一致した後にundefinedにインデックスを設定する理由です。もしそうであれば

  2. indexOf戻り要素のそれが要素を見つけることができれば、それは-1がtruthyので、要素が見つからない場合は、お使いの比較がtrueを返し、0はfalsyで、見つけて、任意の数の>= 0ことができないため-1、要素が2番目の配列の最初のインデックスにある場合、メソッドはfalseを返します(つまり、every ...のために、すべてがfalseになります)。したがって、indexOfの結果の前に~を追加してください:~arr2.indexOf(element)

    は、ビット単位のNot演算子(~)とどのようにそれは私が述べた indexOfの問題を解決するにthis MDNページを参照してください。

    this真実/偽の値についての回答と、それらが&&および||とどのように相互作用するかを見てみることをお勧めします。


だから、(そこにはindexOfが使用されていないと私は問題#2を固定している以外には、ほとんどがあなたの例だ)、これを試してみてください:

function _compareArrays(arr1,arr2){ 
 
    if(!(arr1 != null && arr2 != null && arr1.length == arr2.length)) { 
 
    return false; 
 
    } 
 

 
    /* copy the arrays so that the original arrays are not affected when we set the indices to "undefined" */ 
 
    arr1 = [].concat(arr1); 
 
    arr2 = [].concat(arr2); 
 

 
    return arr1.every(function(element, index) { 
 
    return arr2.some(function(e, i) { 
 
     return e === element && (arr2[i] = undefined, true); 
 
    }); 
 
    }); 
 
} 
 
    
 
var x = ["str", "boo", "str"]; 
 
var y = ["boo", "str", "str"]; 
 
var z = ["abc", "def", "ghi"]  
 

 
console.log(_compareArrays(x, y)); 
 
console.log(_compareArrays(x, z)); 
 
console.log(_compareArrays(z, z));

それは勝ちました配列にundefined要素がある場合は動作しません。

+0

なぜ配列の値を変更しますか?私は値を保持したいと思います。 – sarah

+0

関数の開始時に未定義の値をすべてnullに設定できます。しかし、それはちょっとしたジャンク解です。 – nipuna777

+1

@sarahそうでなければ[1,2,1]は[1,2,2]と等しいとマークされます。 – nipuna777

1

代わりにオブジェクトに配列を変換します。配列の値をキーに変換し、それぞれの値を値に変換します。これは、配列に対して一度だけ反復処理を実行するほどパフォーマンスが向上します。

function compare(a, b) { 
    if (a.length !== b.length) { 
    return false; 
    } 
    let set = {}; 
    a.forEach((i) => { 
    if (set[i] !== undefined) { 
     set[i]++; 
    } else { 
     set[i] = 1; 
    } 
    }); 
    let difference = b.every((i) => { 
    if (set[i] === undefined) { 
     return false; 
    } else { 
     set[i]--; 
     if (set[i] === 0) { 
     delete set[i]; 
     } 
     return true; 
    } 
    }); 
    return Object.keys(set) == 0 && difference; 
} 

集合(オブジェクト)を初期化最初の配列の最初のループ、第二のアレイ上の第二のループは、カウントを減算し、キーが見つかった場合、またはされていない場合はカウントが0に達したとき、キーを削除しますプロシージャの最後にセットが空でない場合、配列は似ていません。

関連する問題