3

ループごとにアンダースコア内で値を返しているときに、少なくとも1つは理解できない奇妙な動作に気付きました。私のコードは次のとおりです。基本的に、次のように、要素がその ID に基づいて配列に既に存在するかどうかをテストします。

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = function(key, val){
    _.each(elements,function(element){
        console.log(element[key], val);
        if(element[key] == val){
            console.log("element exists");
                return true;
        }
   });
   return false;
};

console.log("true : ", element_exists("id", "1"));
console.log("false : ", element_exists("id", "2"));

コンソールに次のログが表示されます。

1 1
element exists
3 1
true : false
1 2
3 2
false : false

私の質問は、関数が最初の要素に対して true を返さないのはなぜですか?

4

3 に答える 3

6

@ltbeshあなたは間違っています!関数値を返し、停止します。入力の残りの要素に対して iterator 関数の実行を継続するだけです。

_.eachループステートメントとメソッドを混同しています。

メソッドの 2 番目のパラメーター_.eachは、イテレーター関数です。これは基本的に、配列のすべての要素に対して実行される関数です。したがって、returnイテレータ関数にステートメントを記述すると、その特定の関数呼び出しのみが終了します。関数は、配列内の残りの要素に対して引き続き呼び出されます。

アップデート


UnderscoreJS ソリューション

代わりに使用する必要があるのは_.find、または_.someアンダースコア メソッドです。(まあ、2020 年になったので、ES6 がすぐに使える機能を得るためにアンダースコアとロダッシュの使用を放棄する時が来ました)。しかし、質問はunderscoreJSに関するものなので、最初にアンダースコアを使用して解決策を提供します。

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = function(key, val){
    return _.find(elements,function(element){
        return element[key] === val;
   });
};

console.log("true : ", element_exists("id", "1"));
console.log("false : ", element_exists("id", "2"));
<script src="https://underscorejs.org/underscore-min.js"></script>

ES6 ベースのソリューション

ここで、外部ライブラリなしで ES6 で同じ機能を実現することがいかに簡潔かを示すために、ES6 バージョンを示します。

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = (key, val) => (
    elements.find(element => element[key] === val)
)

console.log("true : ", element_exists("id", "1"));
console.log("false : ", element_exists("id", "2"));

PS: 要素が存在するかどうかのみを確認し、メソッドによって返されたくない場合は、使用からelement_existsに切り替えます。findsome

于 2013-11-06T13:09:41.940 に答える
1

これは、関数から常に false を返しているために発生しています。

機能を継続して使用する場合は、これに書き換えeach()ます。

var elements = [{id: "1", name : "foo"},{id : "3", name: "bar"}];

element_exists = function(key, val){
  var someFlag = false;  
  _.each(elements, function(element){
        console.log(element[key] +" - "+ val);
        if(element[key] == val){
            console.log("element exists");
            someFlag = true;
        }
   });
   return someFlag;
};

console.log("should be true : " + element_exists("id", "1"));
console.log("should be false : " +element_exists("id", "2"));
于 2013-10-25T07:05:09.093 に答える