アンダースコアで特定のキー値を持つオブジェクトの配列インデックスを見つける


91

アンダースコアでは、特定のキー値を持つアイテムを正常に見つけることができます

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
//data = { id: 2 }

しかし、そのオブジェクトが発生した配列インデックスを見つけるにはどうすればよいですか?



おかげで-これは便利です-記載されている例では、数値の配列で単一の数値を検索しています-オブジェクトの配列でキー値を探しています。この機能はそれに対応しますか?
mheavers 2014

2
数値テストであれ、プロパティの平等性述語であれ、問題ではありません。
ベルギ14

試してみてくださいfindIndexvar dataIndex = _.findIndex(tv, { id: voteID })
トムSöderlund

質問で要求されているように、アンダースコアソリューションを提供する回答を受け入れることを検討しください。
Nigel B. Peck

回答:


28

これを行う既存の下線メソッドがあるかどうかはわかりませんが、プレーンなJavaScriptで同じ結果を得ることができます。

Array.prototype.getIndexBy = function (name, value) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][name] == value) {
            return i;
        }
    }
    return -1;
}

その後、あなたはただ行うことができます:

var data = tv[tv.getIndexBy("id", 2)]


4
なぜreturn -1;デフォルトではないのですか?
Radu Chiriac

171

findIndex 1.8で追加されました:

index = _.findIndex(tv, function(voteItem) { return voteItem.id == voteID })

見る: http //underscorejs.org/#findIndex

または、別の一時リストを作成してもかまわない場合、これも機能します。

index = _.indexOf(_.pluck(tv, 'id'), voteId);

参照:http : //underscorejs.org/#pluck


下線についてはわかりませんが、lodashでは無名関数は必要ありません。単に機能します。コレクションがより複雑な値(プロパティだけではない)を持ってindex = _.findIndex(tv, {id: voteID})いる場合にも機能tvidます
Scott Jungwirth

1
pluckを使用するポイントは非常に遅くなります。私はその余分なトラバースのために。jsperf.com/compare-find-index
Farshid Saberi

38

述語関数をより柔軟にできるようにアンダースコアを使い続けたい場合は、2つのアイデアがあります。

方法1

の述語_.findは要素の値とインデックスの両方を受け取るため、次のように副作用を使用してインデックスを取得できます。

var idx;
_.find(tv, function(voteItem, voteIdx){ 
   if(voteItem.id == voteID){ idx = voteIdx; return true;}; 
});

方法2

アンダースコアソースを見ると、次のよう_.findに実装されています。

_.find = _.detect = function(obj, predicate, context) {
  var result;
  any(obj, function(value, index, list) {
    if (predicate.call(context, value, index, list)) {
      result = value;
      return true;
    }
  });
  return result;
};

これをfindIndex関数にするには、行result = value;result = index;これで置き換えます。これは最初の方法と同じ考えです。下線_.findも副作用を使用して実装することを指摘するために含めました。


37

アンダースコアを拡張するLo-Dashにはは、特定のインスタンスのインデックス、特定の述語、または特定のオブジェクトのプロパティに応じたfindIndexメソッドがあります。

あなたの場合、私はします:

var index = _.findIndex(tv, { id: voteID });

試してみる。


findIntexそれはアンダースコアからではなく、ローダッシュからのメソッドです
Wallysson Nunes

4
@WallyssonNunesこれはまさに私が書いたものです-「アンダースコアを拡張するLo-DashにはfindIndexメソッドがあります」
splintor

3
これは、バージョン1.8.0以降、標準のアンダースコアライブラリの一部になりました:underscorejs.org/#1.8.0
Gage Trader

10

ターゲット環境がES2015をサポートしている場合(または、バベルなどのトランスパイルステップがある場合)、ネイティブのArray.prototype.findIndex()を使用できます。

あなたの例を考えると

const array = [ {id:1}, {id:2} ]
const desiredId = 2;
const index = array.findIndex(obj => obj.id === desiredId);

4

indexOfからメソッドを使用できますlodash

var tv = [{id:1},{id:2}]
var voteID = 2;
var data = _.find(tv, function(voteItem){ return voteItem.id == voteID; });
var index=_.indexOf(tv,data);

3

シンプルに保つ:

// Find the index of the first element in array
// meeting specified condition.
//
var findIndex = function(arr, cond) {
  var i, x;
  for (i in arr) {
    x = arr[i];
    if (cond(x)) return parseInt(i);
  }
};

var idIsTwo = function(x) { return x.id == 2 }
var tv = [ {id: 1}, {id: 2} ]
var i = findIndex(tv, idIsTwo) // 1

または、嫌いでない人のために、CoffeeScriptバリアント:

findIndex = (arr, cond) ->
  for i, x of arr
    return parseInt(i) if cond(x)

1
より良いでしょうreturn parseInt(i) for i, x of array when cond(x)
貧弱

1
これは以前の答えよりも簡単ですか?
ncubica 2015年

2

これはlodashユーザーを助けるためです。次のようにして、キーが存在するかどうかを確認します。

hideSelectedCompany(yourKey) {
 return _.findIndex(yourArray, n => n === yourKey) === -1;
}

1

最も簡単な解決策は、lodashを使用することです。

  1. lodashをインストールします。

npm install --save lodash

  1. メソッドfindIndexを使用します。

const _ = require( 'lodash');

findIndexByElementKeyValue = (elementKeyValue) => {
  return _.findIndex(array, arrayItem => arrayItem.keyelementKeyValue);
}

0

複数の一致が予想されるために配列を返す必要がある場合は、次のことを試してください。

_.where(Users, {age: 24})

プロパティ値が一意であり、一致のインデックスが必要な場合は、以下を試してください。

_.findWhere(Users, {_id: 10})

0
Array.prototype.getIndex = function (obj) {
    for (var i = 0; i < this.length; i++) {
        if (this[i][Id] == obj.Id) {
            return i;
        }
    }
    return -1;
}

List.getIndex(obj);

0

私は同様のケースを手に入れましたが、逆に、与えられたオブジェクトのインデックスに基づいて使用されたキーを見つけることです。アンダースコアを使用Object.valuesしてオブジェクトを配列に返し、発生したインデックスを取得することで解決策を見つけることができました。

var tv = {id1:1,id2:2};
var voteIndex = 1;
console.log(_.findKey(tv, function(item) {
  return _.indexOf(Object.values(tv), item) == voteIndex;
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.