Следующая операция называется фильтрация. В PHP она выполняется с помощью функции array_filter
, а в других языках ее называют просто filter
или select
.
Понятие «фильтрация» интуитивно понятно каждому человеку. Мы пьем фильтрованную воду и фильтруем то, что говорим. В программировании практически то же самое. Фильтрация по отношению к коллекции означает, что мы отбираем из нее только те элементы, которые удовлетворяют условию.
Возьмем наших многострадальных пользователей и выберем тех, кто старше 10 лет:
<?php
$users = [
['name' => 'Igor', 'age' => 19],
['name' => 'Danil', 'age' => 1],
['name' => 'Vovan', 'age' => 4],
['name' => 'Matvey', 'age' => 16],
];
$result = [];
foreach ($users as $user) {
if ($user['age'] > 10) {
$result[] = $user;
}
}
print_r($result);
// => Array
// (
// [0] => Array
// (
// [name] => Igor
// [age] => 19
// )
//
// [1] => Array
// (
// [name] => Matvey
// [age] => 16
// )
//
// )
Фильтрация встречается так же часто, как отображение, а возможно и чаще. Общая схема кода при фильтрации практически такая же, как и в отображении. Отличается только пара ключевых моментов:
- Фильтрация возвращает коллекцию либо того же размера (если ничего не было отфильтровано), либо меньшего. Она может вернуть даже пустую коллекцию, если ни один из элементов не подошел
- Фильтрация всегда возвращает исходные элементы. Она никогда не делает отображение. Если на вход фильтрации поступил список пользователей, то список пользователей будет и на выходе
Теперь посмотрим, как выглядит фильтрация при использовании функции высшего порядка array_filter
:
<?php
// Порядок аргументов обратный
// Сначала идет коллекция, а затем — функция
// $user – это элемент массива $users
$filteredUsers = array_filter($users, fn($user) => $user['age'] > 10);
В отличие от array_map
, переданная в array_filter
функция должна быть предикатом. Другими словами, она должна вернуть true
или false
для каждого элемента коллекции. Значение, которое возвращается никак не используется. Оно всего лишь говорит о том, стоит ли включать текущий элемент в итоговый массив. Новички часто делают ошибку на этом этапе и начинают возвращать из фильтра то, что они бы хотели увидеть в результирующем массиве. На самом деле, для этого надо применять array_map
.
Перейдем к реализации:
<?php
function myFilter($coll, callable $callback)
{
$result = [];
foreach ($coll as $key => $item) {
// Предикат используется только для проверки
// Внутрь $callback по очереди передается каждый элемент коллекции $coll
if ($callback($item)) {
// В результат всегда добавляется элемент исходной коллекции
$result[$key] = $item;
}
}
return $result;
}
Обратите внимание, что array_filter
сохраняет ключи. При работе с индексированными массивами такое поведение нежелательно, поэтому придется использовать функцию array_values
для сброса порядка.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.