web-dev-qa-db-ja.com

オブジェクトがコレクション内にあるかどうかを確認するために、lodashで含まれるのはメソッドをどうように使用しますか?

lodashは私がincludesで基本的なデータ型のメンバーシップをチェックすることを可能にします:

_.includes([1, 2, 3], 2)
> true

しかし、以下はうまくいきません。

_.includes([{"a": 1}, {"b": 2}], {"b": 2})
> false

コレクションを検索する次のメソッドは問題ないようです。

_.where([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
_.find([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}

何がおかしいのですか? includesを使用して、コレクション内のオブジェクトのメンバーシップを確認する方法を教えてください。

編集:質問はもともとlodashのバージョン2.4.1、lodash 4.0.0のためにあった

111
Conrad.Dean

includes (以前はcontainsおよびincludeと呼ばれていました)メソッドはオブジェクトを参照によって(より正確には===と)比較します。この例の{"b": 2}の2つのオブジェクトリテラルは、異なるインスタンスを表しているため、等しくありません。通知:

({"b": 2} === {"b": 2})
> false

ただし、{"b": 2}のインスタンスは1つしかないため、これは機能します。

var a = {"a": 1}, b = {"b": 2};
_.includes([a, b], b);
> true

一方、 where (v4では廃止予定)メソッドと find メソッドはそれぞれのプロパティでオブジェクトを比較するため、参照の等価性は必要ありません。 includesの代わりに、 some を試してみることもできます(anyのエイリアスもあります)。

_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true
173
p.s.w.g

p.s.w.gで答えを補足する、これを達成するための他の3つの方法はlodash4.17.5使わずに_.includes()です:

entryがまだ存在しない場合に限り、オブジェクトnumbersをオブジェクトentryの配列に追加したいとします。

let numbers = [
    { to: 1, from: 2 },
    { to: 3, from: 4 },
    { to: 5, from: 6 },
    { to: 7, from: 8 },
    { to: 1, from: 2 } // intentionally added duplicate
];

let entry = { to: 1, from: 2 };

/* 
 * 1. This will return the *index of the first* element that matches:
 */
_.findIndex(numbers, (o) => { return _.isMatch(o, entry) });
// output: 0


/* 
 * 2. This will return the entry that matches. Even if the entry exists
 *    multiple time, it is only returned once.
 */
_.find(numbers, (o) => { return _.isMatch(o, entry) });
// output: {to: 1, from: 2}


/* 
 * 3. This will return an array of objects containing all the matches.
 *    If an entry exists multiple times, if is returned multiple times.
 */
_.filter(numbers, _.matches(entry));
// output: [{to: 1, from: 2}, {to: 1, from: 2}]

Booleanを返したい場合、最初のケースでは、返されているインデックスを確認できます。

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true
6
Mihai