web-dev-qa-db-ja.com

underscore.jsを使用して配列内のオブジェクトのインデックスを見つけるにはどうすればよいですか?

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。その機能には入っていないので。だから私はその警告メッセージを受け取りませんでした。

私のコードに何が問題なのか。誰か助けてもらえますか?

10
prince

代わりにこれを使用してください:

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を使用することです。

14
Minko Gechev

ロダッシュを見てみることを強くお勧めします。残念ながらアンダースコアに欠けているかなり気の利いた小さな関数が含まれています。

たとえば、これは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

ES2015が(Babelのようなトランスパイラーを介して)広く使用されるようになったので、手元のタスクのロダッシュとアンダースコアーを無視して、ネイティブメソッドを使用できます。

var arr = [{ id: 1 }, { id: 2}];

arr.findIndex(i => i.id === 1); // 0
15
Kasper Lewau

私の提案はあなたに助言を与えるでしょう。

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
n_n

オブジェクトあり、===および== 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 を使用できます。

2
T.J. Crowder

複雑なオブジェクトがあり、特定のプロパティを探してコレクション内の1つのオブジェクトを検索する場合は、次のようにします。

 _.indexOf(arrayObj, _.findWhere(arrayObj, {id: 1})  );

ここで、「arrayObj」はオブジェクトのコレクション、「id」はプロップ、「1」は検索対象の値です。

1
Nicolae Lozovan
_.find(array, function(item, index) {
  if (item.id == searchValue.id) {
    alert(index);
  }
});
0
riyas tk