Как сделать фильтрацию js

Обновлено: 08.07.2024

ECMAScript 5 имеет filter() прототип для Array типов, но не для Object типов, если я правильно понимаю.

Как бы я реализовать filter() для Object s в JavaScript?

Допустим, у меня есть этот объект:

И я хочу написать, filter() что работает на Object с:

Это работает, когда я использую его в следующей демонстрации, но когда я добавляю его на свой сайт, который использует jQuery 1.5 и jQuery UI 1.8.9, я получаю ошибки JavaScript в FireBug.

именно то, что мне нужно, кроме того, что вы должны удалить "!" в предикате! (этот [ключ]) иметь реальный метод фильтра.

Никогда не расширяйся Object.prototype .

Ужасные вещи будут происходить с вашим кодом. Вещи сломаются. Вы расширяете все типы объектов, включая литералы объектов.

Вот быстрый пример, который вы можете попробовать:

Вместо этого создайте функцию, которую вы передаете объекту.

@patrick: дай человеку хлеб, и ты накормишь его на день, научишь его выпекать и накормишь его на всю жизнь (или что-то, я датчанин, я не знаю правильных английских высказываний) ;)

@pyrotechnick: Нет. Во-первых, суть ответа не в том, чтобы расширить Object.prototype , а просто вложить функцию Object . Во-вторых, это код ОП . Ясно, что намерение ОП состоит в том, чтобы иметь .filter() возможность отфильтровывать положительные результаты. Другими словами, это отрицательный фильтр, где положительное возвращаемое значение означает, что оно исключено из результата. Если вы посмотрите на пример jsFiddle, он отфильтровывает существующие свойства undefined .

Прежде всего, расширение считается плохой практикой Object.prototype . Вместо этого, обеспечить вашу функцию в качестве функции полезности на Object , так же , как там уже есть Object.keys , Object.assign , Object.is . и т.д..

Я приведу здесь несколько решений:

  1. Использование reduce и Object.keys
  2. Как (1), в сочетании с Object.assign
  3. Использование map и распространение синтаксиса вместо reduce
  4. Использование Object.entries и Object.fromEntries

1. Использование reduce и Object.keys

С помощью reduce и Object.keys реализовать желаемый фильтр (используя синтаксис стрелки ES6 ):

Обратите внимание, что в приведенном выше коде predicate должно быть условие включения (в отличие от условия исключения используемого OP), чтобы оно соответствовало тому, как Array.prototype.filter работает.

2. Как (1), в сочетании с Object.assign

В приведенном выше решении оператор запятой используется в reduce части для возврата мутированного res объекта. Конечно, это можно записать в виде двух утверждений вместо одного выражения, но последнее является более кратким. Для того, чтобы сделать это без оператора запятая, вы можете использовать Object.assign вместо этого, который действительно возвращает мутантный объект:

3. Использование map и распространение синтаксиса вместо reduce

Здесь мы перемещаем Object.assign вызов из цикла, чтобы он выполнялся только один раз, и передаем отдельные ключи в качестве отдельных аргументов (используя синтаксис распространения ):

4. Использование Object.entries и Object.fromEntries

Поскольку решение переводит объект в промежуточный массив, а затем преобразует его обратно в простой объект, было бы полезно использовать Object.entries (ES2017) и наоборот (т.е. создать объект из массива пар ключ / значение ) с помощью Object.fromEntries ( ES2019).

Функция предиката получает здесь пару ключ / значение в качестве аргумента, которая немного отличается, но допускает больше возможностей в логике функции предиката.

Метод массивов filter() создает новый массив из элементов существующего массива, которые отвечают заданным критериям:

var numbers = [1, 3, 6, 8, 11];
var lucky = numbers.filter(function(number) return number > 7;
>);
// [ 8, 11 ]

В приведенном выше примере используется массив numbers. В результате возвращается новый фильтрованный массив, содержащий только те значения, которые больше 7.

Синтаксис метода filter()

var newArray = array.filter(function(item) return condition;
>);

Аргумент item – это ссылка на текущий элемент в массиве, поскольку filter() проверяет его на соответствие условию. В случае объектов это позволяет получить доступ к свойствам.

Если текущий элемент соответствует условию, он отправляется в новый массив.

Фильтрация массива объектов

Типичный вариант использования метода .filter() – это фильтрация массива объектов по их свойствам:

Дополнительные ресурсы

Дополнительную информацию о методе filter() вы найдете на MDN.

Метод filter() – это лишь один из нескольких методов итерации массивов в JavaScript.

В статье приведено 15 примеров использование в Javascript функций map(), reduce() и filter() . Когда вы читаете о Array.reduce и о том как это круто, вы часто можете встретить один и то же пример, показывающий использование этой функции. Этот пример демонстрирует суммирование списка чисел. Проблема с этим примером в том что, я никогда не видел использование этого примера в реальных проектах. Тем не менее, я часто вижу лишних 7–8 строк операторов цикла для решения довольно обычных задач, которые при использование Array.reduce всегда можно преобразовать в одну строку.

Недавно я прорефакторил несколько модулей с использованием этих замечательных функций и был шокирован тем, насколько удобнее стало читать код. Итак, ниже приведен список вкусностей. Также не стесняйтесь размещать свои примеры в разделе комментариев.

1. Удаление дубликатов из массива числе/строк

Это единственный пример, который не относится в нашем обзоре, к map/reduce/filter, но он настолько компактный, что трудно было не поместить его в список. Кроме того, мы будем использовать похожий код в нескольких примерах.

2. Простой поиск (чувствительный к регистру)

Метод filter() создает новый массив со всеми элементами, которые проходят условие, реализованного предоставленной функцией.

3. Простой поиск (не чувствительный к регистру)

4. Проверка есть ли у пользователей права администратора

Метод some() проверяет, соответствует ли хотя бы один элемент в массиве условию, реализованному в предоставленной функцией.

5. Сглаживание массива массивов

Код решает задачу преобразования массива массивов в один плоский массив. Результат первой итерации будет равен: […[], …[1, 2, 3]] что означает, что он преобразуется в [1, 2, 3] — это значение мы предоставляем как ‘acc’ на второй итерации и так далее.

Вероятно, это самая короткая реализация для создания массива (метод Array.flat все еще является экспериментальной функцией). Обратите внимание на то, что использование оператора spread внутри функции reduce не очень хорошо с точки зрения производительности. Этот пример того случая, когда производительностью можно пренебречь только если позволяет контекст использования ☝️

6. Создание объекта, который содержит частоту использования ключей

Давайте сгруппируем и посчитаем свойство ‘age’ для каждого элемента в массиве:

7. Индексирование массива объектов (таблица соответствий)

Вместо того, чтобы проходить через весь массив во время поиска пользователя по идентификатору, мы можем создать объект, в котором идентификатор пользователя представляет ключ (с постоянным временем поиска).

Это особенно полезно когда вам часто приходится обращаться к данным следующим образом uTable[85].name a lot.

8. Извлечение уникальных значений для определенного ключа для каждого элемента в массиве.

Давайте создадим список групп пользователей. Метод map() создаст новый массив с результатами вызова предоставленной функции для каждого элемента в вызывающем массиве.

9. Обратное мапирование объекта типа ключ/значение

Этот однострочник выглядит довольно сложно. Мы используем оператор comma (запятая), что означает, что мы возвращаем последнее значение в скобках — acc. Давайте перепишем этот пример более production-ready способом:

10. Создание массива значений Фаренгейта из массива значений Цельсия

Думайте об этом примере как о примере с обработкой каждого элемента массива заданной формулой 🤓

11. Кодировать объекта в строку запроса

12. Отображение таблицы пользователей в виде читаемой строки только с указанными ключами

В определенных случаях вам может понадобится отобразить массив объектов с выбранными ключами в виде строки, но без использования JSON.stringify . 😦Например из-за необходимость исключение определенных ключей.

13. Поиск и замена пары ключ-значение в массиве объектов

Допустим нам понадобилось изменить возраст Джона. Если мы будем знать индекс, мы можем легко это сделать с помощью: users[1].age = 29 . Однако у нас есть и другая возможность это сделать:

Здесь вместо того, чтобы изменять один элемент в нашем массиве, мы создаем новый массив с отличием только в одном элементе. Теперь мы можем сравнивать наши массивы только по ссылкам updatedUsers == users, что очень быстро работает! React.js использует такой же подход для ускорения процесса согласования. Подробнее об этом можно почитать здесь.

14. Объединение (A ∪ B) массивов

С меньшим кодом чем использование метода lodash union.

15. Поиск пересечений в массивах (A ∩ B)

Это последний пример!

В качестве упражнения можете попытаться реализовать поиск разницы в массивах (A \ B). Подсказка: используйте восклицательный знак.

Завершение!

Надеюсь моя статься окажется вам полезной. Если у вас есть какие-либо вопросы или пожелания, дайте мне знать в комментариях ниже.


Доброго времени суток, уважаемый читатель!

Недавно меня попросили помочь решить одну простенькую задачку.

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

Условие

Дан одномерный массив из 7 элементов. Необходимо посчитать количество элементов, находящихся на нечетных позициях и имеющие нечетное значение.

Посмотрим, как можно решить такую задачу.

Вариант решения №1

Первое, что мне пришло на ум — создать цикл for, в котором поставить обычные проверки на нечетность. Ниже привожу пример:

Мы создаем массив, пробегаем по циклу весь массив от 0 до array.length (7) и проверяем. Если позиция нечетная i%2 (вернет 1, если позиция 1, 3, 5…) и если значение элемента нечетное (array[i]%2 вернет 1, если значение нечетное), то увеличиваем счетчик на единицу. В конце распечатываем количество элементов q.

Это один вариант решения, давайте теперь посмотрим другой вариант.

Вариант решения №2. Использование filter()

Второй вариант заключается в том, что мы весь массив прогоняем с помощью метода filter() и проверяем, удовлетворяет ли значение элемента массива нашему условию:

Данное решение выглядит немного элегантней и занимаем немного меньше места 🙂

Теперь разберем, как же работает метод filter().

Как работает filter()

Функция возвращает элементы массива, удовлетворяющие условию, которые указанны в функции обратного вызова.

array1 — Обязательный. Объект массива.

callback — Обязательный. Метод filter вызывает функцию callback для каждого элемента массива по одному разу.

thisArg — Необязательный. Объект, на который будет ссылаться ключевое слово this в callback. Если аргумент thisArg не задан, то для значения this используется undefined.

Возвращаемые значения

После обработки возвращается новый массив, содержащий все значения, для которых функция обратного вызова возвращает значение true. Если функция вернула значение false для всех элементов массива, то длина нового полученного после обработки массива будет равна 0.

Функция callback в методе filter()

Функция callback принимает до 3-х параметров. Все параметры необязательные. Ниже приведены пояснения параметров.

Еще пример

Под конец приведу еще один маленький пример.

Заключение

Вот и все. Мы разобрали, что делает функция filter() и решили с помощью нее простенькую задачу. Надеюсь, что все было понятно, а если нет — то спрашивайте в комментариях, вместе подумаем! 😉

Спасибо за внимание! Подписывайтесь на рассылку!

Автор статьи: Alex. Категория: JavaScript
Дата публикации: 25.05.2013

Читайте также: