Avatar ·

В чем разница между array_map, array_walk и array_filter в PHP?

Всем привет! Я только начал изучать PHP и никак не могу понять разницу между функциями array_map, array_walk и array_filter. Вроде бы все они принимают callback и применяют его к массиву. Но когда я пытаюсь использовать их в реальном коде, результаты получаются разные или я вообще не понимаю, какую из них выбрать. Например, у меня есть массив чисел: ```php $numbers = [1, 2, 3, 4, 5]; ``` Я хочу: 1. Умножить каждое число на 2. 2. Вывести каждое число с префиксом "Number: ". 3. Отфильтровать только четные числа. Я пробовал array_map: ```php $doubled = array_map(function($n) { return $n * 2; }, $numbers); ``` Вроде работает, возвращает новый массив. Но array_walk тоже можно использовать? Или array_filter? Пробовал array_walk: ```php array_walk($numbers, function(&$n) { $n *= 2; }); ``` Теперь $numbers изменился. А если я хочу просто вывести, а не менять? И array_filter: ```php $even = array_filter($numbers, function($n) { return $n % 2 == 0; }); ``` Тут вроде понятно — фильтрация. Но когда я читаю документацию, там написано, что array_map создает новый массив, array_walk изменяет исходный или просто выполняет действие, а array_filter фильтрует. Но в каких случаях что использовать? Можно ли array_map использовать для фильтрации? Или array_walk для создания нового массива? Помогите разобраться, а то я запутался окончательно. Буду благодарен за примеры с пояснениями! <<>>

Основные различия между array_map, array_walk и array_filter

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

1. array_map — создание нового массива

Назначение: Применить callback к каждому элементу и вернуть новый массив с результатами. Исходный массив не изменяется.

<?php
$numbers = [1, 2, 3, 4, 5];

// Умножаем каждый элемент на 2 — возвращается новый массив
$doubled = array_map(function($n) {
    return $n * 2;
}, $numbers);

print_r($doubled); // [2, 4, 6, 8, 10]
print_r($numbers); // [1, 2, 3, 4, 5] — исходный не изменился
?>

Ключевая особенность: Callback должен возвращать значение. Результат — новый массив той же длины, что и исходный.

2. array_walk — выполнение действия или модификация по ссылке

Назначение: Применить callback к каждому элементу. Возвращает true/false (успех/неудача), а не новый массив. Используется для:

  • Изменения исходного массива (передача по ссылке &$value)
  • Выполнения побочных действий (например, echo, запись в файл)
<?php
$numbers = [1, 2, 3, 4, 5];

// Пример 1: Модификация исходного массива
array_walk($numbers, function(&$value) {
    $value *= 2;
});
print_r($numbers); // [2, 4, 6, 8, 10] — исходный изменен!

// Пример 2: Просто вывод без изменения
$numbers = [1, 2, 3, 4, 5];
array_walk($numbers, function($value) {
    echo "Number: $value\n";
});
// Выведет: Number: 1, Number: 2 и т.д.
// Массив остался прежним
?>

Ключевая особенность: Callback может не возвращать ничего. Если нужно изменить массив — используйте &$value в параметрах.

3. array_filter — фильтрация массива

Назначение: Отфильтровать массив, оставив только элементы, для которых callback вернул true. Возвращает новый массив с сохранением ключей.

<?php
$numbers = [1, 2, 3, 4, 5];

// Оставляем только четные числа
$even = array_filter($numbers, function($n) {
    return $n % 2 == 0;
});

print_r($even); // [1 => 2, 3 => 4] — ключи сохраняются!
// Если нужно сбросить ключи: array_values($even)
?>

Ключевая особенность: Callback возвращает true/false. Длина результирующего массива может быть меньше исходного.

Сводная таблица

Функция Возвращает Изменяет исходный массив? Длина результата Типичное использование
array_map Новый массив Нет Равна исходной Трансформация данных
array_walk true/false Да (если &$value) Не применимо Побочные эффекты, модификация
array_filter Новый массив Нет Меньше или равна Отбор элементов

Практические рекомендации

  • Хотите новый массив с преобразованными данными? → array_map
  • Хотите изменить существующий массив? → array_walk с &$value
  • Хотите выполнить действие (вывести, записать) без изменения? → array_walk
  • Хотите отфильтровать массив по условию? → array_filter

Запомните главное правило: array_map — это "map" (преобразование), array_filter — это "filter" (фильтр), array_walk — это "walk" (прогулка по массиву для действий).

<<>>

Дополнение: array_map с несколькими массивами и array_filter без callback

Есть еще несколько нюансов, которые стоит знать, чтобы полностью освоить эти функции.

array_map с несколькими массивами

Это уникальная возможность: array_map может принимать несколько массивов одновременно. Callback получит столько аргументов, сколько массивов передано:

<?php
$names = ['Alice', 'Bob', 'Charlie'];
$ages = [25, 30, 35];

$combined = array_map(function($name, $age) {
    return "$name is $age years old";
}, $names, $ages);

print_r($combined);
// ['Alice is 25 years old', 'Bob is 30 years old', 'Charlie is 35 years old']
?>

array_filter без callback

Если не передать callback, array_filter удалит все "ложные" значения (false, null, 0, '', пустой массив):

<?php
$mixed = [0, 1, '', 'hello', null, true, false];
$clean = array_filter($mixed);
print_r($clean); // [1 => 1, 3 => 'hello', 5 => true]
?>

array_walk и ключи

array_walk передает в callback не только значение, но и ключ (как второй аргумент). Это удобно для работы с ассоциативными массивами:

<?php
$user = ['name' => 'John', 'age' => 30, 'city' => 'NY'];
array_walk($user, function($value, $key) {
    echo "$key: $value\n";
});
?>

Итог: array_map — для трансформации, array_filter — для отбора, array_walk — для итерации с побочными эффектами. Выбирайте по задаче!