2017-04-22 10 views
2

私はちょっと混乱しています。私はfreeCodeCampに挑戦しています。forEach/for ...値を返さないのですか?

述語(第二引数)は、コレクション(最初の引数)のすべての要素にtruthyであればすべてが

チェックトゥルーを次のように

challengeを読み込みます。

これは解決されましたが、なぜ私は余分なステップを踏まなければならなかったのか分かりません。私のコードは次のような次のとおりです。

function truthCheck(collection, pre) { 
    collection.forEach(function(element) { 
     for (key in element) { 
      if (!element.hasOwnProperty(pre)) { 
       return false; 
      } else if (key === pre) { 
       if (!Boolean(element[key])) { 
        return false; 
       } 
      } 
     } 
    }); 
    return true; 
} 

truthCheck([ 
    {"user": "Tinky-Winky", "sex": "male"}, 
    {"user": "Dipsy"}, 
    {"user": "Laa-Laa", "sex": "female"}, 
    {"user": "Po", "sex": "female"} 
], "sex"); 

collection内の第二要素がsex性質を持っていないのでので、この例では、それは失敗するはずです。また、pre引数、またはこの場合はsexが真実値でない場合には、失敗を受信します。

これらがヒットしたら(コンソールログを介して伝えることができますが)、ループから抜け出し、truthCheck機能から復帰するとわかります...しかし、それは結局真実を返すでしょう。

私は、変数を定義してその値をfalseに設定し、最後に変数を返すことでこれを回避することができました。より良い方法がありますか?これらのリターンがtruthCheck関数から抜け出すようですか?何か不足していますか?

+0

Foreachは戻り値で何もしません。あなたは代わりに通常のforループを使いたいでしょう。 – Christopher

+0

FYI: 'if(Boolean(element [key]))'は 'if(element [key])'と書くのが簡単です。これは、特定の値がtrueと評価されるものに設定されているかどうかをチェックします。あるオブジェクトが特定の* key *を持っているかどうかを知りたければ、(if *(element.hasOwnProperty(key)) 'を使います。 – Tomalak

答えて

2

を:

collection.forEach(function() { 
    // do something 
    return false; 
}); 

array#forEachが単にないので、そのワーカー関数の戻り値を気にしないでください。各配列要素のワーカー関数を実行するだけです。

function truthCheck(collection, pre) { 
    var allAreTruthy = true; 
    collection.forEach(function (elem) { 
    // if this ever flips allAreTruthy to false, it will stay false 
    allAreTruthy = allAreTruthy && elem[pre]; 
    }); 
    return allAreTruthy; 
} 

をしかし、これを表現するためのより良い方法があります。

あなたは外側の変数を設定するには、労働者の機能を使用することができます。

述語(第2引数)がコレクションのすべての要素(第1引数)について真実であるかどうかをチェックします。

と言い換えることでした「コレクションのすべての要素は、特定のキーでtruthy値を持っています。」

function truthCheck(collection, pre) { 
    return collection.every(function (elem) { return elem[pre]; }); 
} 

は、「コレクションの要素のは、特定のキーでfalsy値を持つ(または完全にキーが欠落している)なし。」と言い換えることでした

あるいは、Array#none方法は、実際に、存在しないため、「特定のキーでfalsy値を持つコレクションの一部要素がありません。」

function truthCheck(collection, pre) { 
    return !collection.some(function (elem) { return !elem[pre]; }); 
} 

Array#someを使用する利点は、それが、すぐにそれがために求めている条件が満たされたとして配列を反復処理を停止していることです。配列に多くの要素がある場合、これはパフォーマンスの向上を意味します。短い配列の場合、Array#everyまたはArray#forEachを使用することとの違いはほとんどありません。あなたが設定されていないキーにアクセスするとJSオブジェクトは、単にhasOwnPropertyのチェックがここに不必要である、undefinedを返すので

上記

function truthCheck(collection, pre) { 
    var i; 
    for (i = 0; i < collection.length; i++) { 
    if (!collection[i][pre]) return false; 
    } 
    return true; 
} 

と意味的に等価です。

2

コレクションの各要素に対して関数を実行します。この関数は、要素anが何かを返すかどうかをチェックします。しかし、その戻り値は外部関数の結果には影響しません。外部関数は内部関数に依存しないので、結果は常に真です。

変数を定義する場合、これをfalseに設定して、その変数を最後に戻しますが、効率が悪くなります。次のシナリオを考えてみましょう。ターゲットキーを持たない要素が1つ見つかりました。だから今は戻ってくるべきですが、できません。コレクション全体を通して自分自身で作業しなければなりません。 forEachループでは、messなしで終了する機会はありません。したがって、ループのためのより良いアイデアはです。ループのためのあなたの缶の出口出口あなたは少し簡単な方法は次のようになり

を探していたものを見つけた場合:

function truthCheck(collection, pre) { 
    //iterate thrugh your collection 
    for (var c in collection){ 
     //get keys of element as an array and check if pre is in that array 
     if(Object.keys(collection[c]).indexOf(pre) == -1){ 
      // pre was not found 
      return false; 
     } 
    } 
    return true; 
} 
2
function truthCheck(collection, pre) { 
    return collection.every(function (person) { return !!person[pre]; }); 
} 
+0

'return person [pre];'は本当のチェックのために十分でしょう。 – Tomalak

+0

Tomalakあなたは正しいです、私は型の一貫性を保つためにブール値に変換しました。 –

+0

「すべて」というのは、それほど差がないということです。 :) – Tomalak

2

[コレクション]のjavascriptの.forEachは普通のループのように動作しません。あなたが例外をスローしない限り、それを途中で終了する方法はありません。

あなたが期待している動作は、javascript forループから期待されるものですが、forEachは各ループオブジェクトに対してコールバック関数を使用するため、forEachの代わりにコールバック関数を終了するだけです。また、あなたのコードでは、あなたはそれに戻りますforループを持っていることに注意する価値があります。このループ内のリターンブロックは、このループを破るだけで、forEach(前に説明したが、そうでない限り早期に終了することはできません)ではありません。

forEachはほとんどの場合、反復ごとの条件チェック素子。

1

ForEachループから何も返すことはできません。デフォルトではundefinedが返されます。公式ドキュメント、Array.prototype.forEach() - JavaScript | MDNとして

、こう述べています。

例外をスローする以外のforEach()ループを停止または中断する方法はありません。このような振る舞いが必要な場合、forEach()メソッドは間違ったツールです。代わりにプレーンループを使用します。述部の配列要素をテストしていて、ブール戻り値が必要な場合は、every()またはsome()を代わりに使用できます。

だから、例えば非常に単純にfor..inループ、使用することができます。他の回答が説明したように、これは無意味である

for(var c in collection){ 
    // Do whatever you want 
} 
関連する問題