Як я можу використовувати метод include у lodash, щоб перевірити, чи є об’єкт у колекції?


146

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


7
_.containsбуло видалено в lodash v4 - використовуйте _.includesзамість цього
Billy Moon

@BillyMoon забуває! так, ти маєш рацію, lodash v4.0.0 (вийшов 2016-01-12) видаляє containsпсевдонім. Я
оновлю

Відповіді:


222

Метод includes(що раніше називався containsі include) порівнює об'єкти за посиланням (а точніше - з ===). Оскільки два об'єктивні літерали {"b": 2}у вашому прикладі представляють різні екземпляри, вони не є рівними. Зверніть увагу:

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

Однак це спрацює, оскільки є лише один примірник {"b": 2}:

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

12

Доповнюючи відповідь p.s.w.g, ось три інші способи досягти цього lodash 4.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}]

Якщо ви хочете повернути a Boolean, у першому випадку ви можете перевірити індекс, який повертається:

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.