2016-09-13 7 views
1

配列をループし、条件の各要素をテストする関数を書いています。 falseの場合、要素は削除されます。 trueの場合、関数は配列の残りの部分を返します。ここで配列の要素がテストに合格していません

は私のコードです:

function dropElements(arr, func) { 
    // Loop through the array 
    for(var i = 0; i < arr.length; i++){ 
     // if the current element passes the test, return the rest of the array 
     if (func(arr[i])){ 
     return arr; 
     // otherwise remove the element 
     } else { 
     arr.shift(); 
     } 
    } 
    // if no conditions were met, return empty array 
    return arr; 
} 

ループは、I = 1に達したとき、私たちはARR持っている[1] 2以来2

を=> = 3ではない、私はなぜ理解していませんそれは落とされません。

だから、なぜ代わりに[3,4]の次の呼び出し

dropElements([1,2,3,4], function(n) {return n >= 3; }); 

リターン[2,3,4]?

ありがとうございました。

+0

「for」を「while」に変更し、while(arr.length){... 'を実行してからif(func(arr [0])){...}。あなたのコードが動作するように、 '0'よりも大きなインデックスにアクセスする状況はありません。 –

答えて

7

「シフト」するとインデックスが削除され、他のインデックスがシフトダウンして穴を埋めるためです。したがって、最初のインデックスを削除すると、2番目のインデックスが1つになります。 iをインクリメントするので、下に移動したインデックスはスキップします。

だからあなたの問題を回避するために、あなたはi

else { 
    arr.shift(); 
    i--; 
} 

を削減する必要があるだろうか、あなたは、インデックスを見つけて、単にアレイを継ぐよりも、別の解決策を行うことができます。 MDNドキュメントから

+0

変数を無意味にすることはできませんか?私はいつも0になるでしょう。 –

0

シフト()メソッドは、配列から最初の要素を取り除き、その要素を返します。このメソッドは、配列の長さを変更します。

コードでは、これはループ内のインデックスを同期する必要があることを意味します。あなたは、単にこの問題を解決します

-1

epascarelloの答えはしかし、ここで、正しいものとして受け入れられるべき1

function dropElements(arr, func) { 
// Loop through the array 
for(var i = 0; i < arr.length; i++){ 
    // if the current element passes the test, return the rest of the array 
    if (func(arr[i])){ 
    return arr; 
    // otherwise remove the element 
    } else { 
    arr.shift();i--; 
    } 
} 
// if no conditions were met, return empty array 
return arr;} 

によって率を低下させることができることは、あなたが必要なもののために更新されたコードブロックです:

function dropElements(arr, func) { 
    // Loop through the array 
    for(var i = 0; i < arr.length; i++){ 
     // if the current element passes the test, remove it from the array 
     if (func(arr[i])){ 
     return arr; 
     } else { 
     arr.shift(); 
     i--; 
     } 
    } 
    // Return the array 
    return arr; 
} 

var arr = [1,2,3,4,2]; 
dropElements(arr, function(num) { 
    return num >= 3; 
}); 

これは[3, 4, 2]を出力します(これは、ループがループしたときに配列が順序付けられ、テスト関数が一度満たされたときに関数から戻ると仮定しているためです)。順序のない配列をループする場合は、ループ内のreturn arrを削除するだけで、これはO(ログn)と反対のO(n)で実行されることに注意してください。

+0

長い配列にありますが、OPがやっているように戻ってループをはるかに速く破ります...配列がソートされていると仮定します – charlietfl

+0

オペレーションが常に順序付き配列でテストされているかどうかはわかりませんでしたが、最初の質問で要件として指定されていなかったので、 '1,2,3,4,2 '桁。私の悪い! – Alex

+0

はソートされていると仮定しなければならない、または配列の残りの部分を正しい方法で返していないと思わなければならない。 – charlietfl

0

この順序は、配列をシフトしています。以下を比較してください:

function dropElements(arr, func) { 
    if (!Array.isArray(arr) && arr.length == 0) { 
     return []; 
    } 

    while (!func(arr[0]) && arr.length > 0) { 
     arr.shift(); 
    } 

    return arr; 
} 
関連する問題