Underscore.jsを使用して、配列内の指定された値のインデックスを取得したいと思います。
これが私のケースです
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue = {'id': 1, 'name': 'xxx'};
私は次のコードを使用しました、
var index = _.indexOf(array, function(data) {
alert(data.toSource()); //For testing purpose
return data === searchValue;
});
これも試しました
var index = _.indexOf(array, {id: searchValue.id});
しかし、それはreturns -1
。その機能には入っていないので。だから私はその警告メッセージを受け取りませんでした。
私のコードに何が問題なのか。誰か助けてもらえますか?
代わりにこれを使用してください:
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue = {'id': 1, 'name': 'xxx'},
index = -1;
_.each(array, function(data, idx) {
if (_.isEqual(data, searchValue)) {
index = idx;
return;
}
});
console.log(index); //0
スニペットでdata === searchValue
はオブジェクトの参照を比較しますが、これを行う必要はありません。一方、data == searchValue
を使用する場合は、オブジェクトの文字列表現を比較します。つまり、toString
メソッドを再定義していない場合は、[Object object]
になります。
したがって、オブジェクトを比較する正しい方法は、_.isEqual
を使用することです。
ロダッシュを見てみることを強くお勧めします。残念ながらアンダースコアに欠けているかなり気の利いた小さな関数が含まれています。
たとえば、これはlodashで行うことです。
var array = [{'id': 1, 'name': 'xxx'},
{'id': 2, 'name': 'yyy'},
{'id': 3, 'name': 'zzz'}];
var searchValue = {'id': 1, 'name': 'xxx'};
var index = _.findIndex(array, searchValue);
console.log(index === 0); //-> true
http://lodash.com/docs#findIndex
また、アンダースコアを使用することにバインドしている場合は、lodashのアンダースコアビルドを https://raw.github.com/lodash/lodash/2.4.1/dist/lodash.underscore.js で取得できます。
ES2015が(Babelのようなトランスパイラーを介して)広く使用されるようになったので、手元のタスクのロダッシュとアンダースコアーを無視して、ネイティブメソッドを使用できます。
var arr = [{ id: 1 }, { id: 2}];
arr.findIndex(i => i.id === 1); // 0
私の提案はあなたに助言を与えるでしょう。
Indexofメソッドにコールバックを使用するのはなぜですか? underscore.jsのindexofのシグネチャは次のとおりです。
_.indexOf(array, value, [isSorted])
このタスクにはfindの方が良いかもしれません:
_.find(array, function(item, index) {
if (item.id == searchValue.id) {
alert(index);
}
});
アンダースコアは、可能な場合はネイティブのindexOfメソッドを使用し、それ以外の場合はフォールバックを適用します。したがって、オブジェクトのリストについては、他の方法で実装する必要があります。
一例は
_.chain(array).pluck("key").indexOf("value").value();
または
_.map(array,function(e) { return e.key; }).indexOf(value);
オブジェクトあり、===
および==
2つの参照がsameオブジェクトを参照しているかどうかを確認します。 equivalentオブジェクトをチェックしません:
var a = {foo: "bar"};
var b = {foo: "bar"};
console.log(a === b); // false, `a` and `b` refer to different (but equivalent) objects
a = b = {something: "here"};
console.log(a === b); // true, `a` and `b` refer to the *same* object
決定を行うには、オブジェクトのプロパティをテストする必要があります。あなたの場合、id
プロパティは適切なオプションのように見えますが、すべてのプロパティを比較したい場合は、アンダースコアの isEqual
を使用できます。
複雑なオブジェクトがあり、特定のプロパティを探してコレクション内の1つのオブジェクトを検索する場合は、次のようにします。
_.indexOf(arrayObj, _.findWhere(arrayObj, {id: 1}) );
ここで、「arrayObj」はオブジェクトのコレクション、「id」はプロップ、「1」は検索対象の値です。
_.find(array, function(item, index) {
if (item.id == searchValue.id) {
alert(index);
}
});