Привет! Спустя почти два года, после последней записи в моём блоге я наконец-то сподобился написать ещё одну заметку. Я хотел сделать это чуточку раньше — на год примерно, а то и полтора — но старая админка моего сайта сломалась, и чинить я её не хотел ибо она была самописная из тех времён, когда я не мог называться даже джуниором. Да и сайт нуждался в кардинальном обновлении. Что я и сделал в свободное от ничего не деланья время.


Эта статья будет полезна новичкам и, надеюсь, более опытным разработчикам, некоторым из которых свойственно использовать одни и те же подходы в одних и тех же ситуациях, даже если существуют другие, возможно более красивые, подходы.

Итак поехали.


Задача

Часто в моей практике мне необходимо проверить содержит ли массив элементы подпадающие под то или иное условие. Это могут быть как простые значения вида [1, 2, 3] так и что-то более сложное в виде массива объектов с разветвлённой структурой. Я для себя выработал пару подходов для этих целей с которыми я вас сейчас и познакомлю.


Итак, создадим для начала наш подопытный массив:

const array = Array.from(Array(5), (element, i) => ({i}))

Получаем вот такой результат:

array = [{"i":0}, {"i":1}, {"i":2}, {"i":3}, {"i":4}]


Кстати, map-функция идущая вторым параметром Array.from при вызове получает два параметра: текущий элемент и его индекс. Об этом даже на MDN не написано :-)

Ладно, продолжим.


Решение

Итак у нас есть массив и нам надо выяснить, есть ли в нём искомый элемент. Будь у нас массив примитивов, то было бы всё очень просто:

array.indexOf(searchElement) >= 0 

Но в нашем случае массив содержит объекты, а значит нужно использовать что-нибудь другое.


Например метод reduce для любителей ES5:

const isContain = array.reduce((prev, curr) => prev || curr.i == 3 , false)

По окончанию работы reduce в переменной isContain будет лежать булево значение true или false.

Для тех, кто хочет использовать ES6 есть вот такой вариант:

const isContain = !!array.find(element => element.i == 3)

Здесь мы дополнительно приводим найденный элемент к булеву значению двумя операторами !!

Или вот таким способом:

const isContain = !!~array.findIndex(element => element.i == 3)

Что ж, не считая магии битовых операторов, это было просто.


Но что же делать если нам надо проверить, что весь массив содержит элементы подходящие под наше условие?

Тут нас спасёт волшебный метод Array.prototype.reduce. Если вы не понимаете как и для чего использовать, то я настоятельно рекомендую потратить время и научится им пользоваться, а пока покажу как его применить для решения нашей задачи:

const isContain = array.reduce(
    (prev, curr) => prev && Number.isInteger(curr.i),
    true
)

Вуаля! Теперь мы знаем содержит ли наш массив подходящие нам элементы (содержит).