Перейти к основному содержимому

Преобразование коллекции

Преобразование берёт коллекцию, например массив, и строит из неё новую коллекцию. Исходная при этом не меняется.

В PHP для массивов есть большое семейство готовых функций: array_map применяет функцию к каждому элементу, array_merge соединяет массивы, array_combine склеивает ключи со значениями, array_column выбирает одну позицию из каждой строки, а implode превращает массив в текст. Там, где готовой функции не находится, задачу решает короткий цикл foreach.

Один и тот же массив PHP работает и как список, и как хранилище ключ:значение. У простого списка ключи 0, 1, 2 и так далее; у ассоциативного массива ключи выбираете вы. И тот и другой хранят свои элементы в порядке добавления, и оба используются на этой странице.


Map

Операция map применяет одну и ту же функцию к каждому элементу и собирает ответы в новый массив той же длины. Например, она может превратить 1, 2, 3 в 3, 6, 9.

В PHP именно это делает array_map: она принимает сначала функцию, а затем массив, и возвращает новый массив. Функцией часто служит короткая стрелочная функция вида fn($x) => $x * 3.

array_map никогда не меняет исходный массив. Она строит и возвращает новый, так что у вас остаются оба.

Map с помощью array_map

array_map вызывает стрелочную функцию для каждого элемента и возвращает новый массив. Здесь она умножает каждое число на 3, а implode выводит новый массив как 3, 6, 9.

Prompt
С помощью array_map и стрелочной функции умножьте каждое число в массиве 1, 2, 3 на 3. Выведите новый массив с помощью implode.
Вывод: PHP-скрипт
Map with array_map

Map с индексом

Иногда важна и позиция элемента. foreach даёт и ключ, и значение, а в простом списке ключи — это позиции 0, 1, 2. Здесь каждое значение умножается на свой индекс, поэтому программа выводит 0, 2, 6.

Prompt
Пройдите по массиву 1, 2, 3 с помощью foreach, используя и ключ, и значение. Постройте новый массив, в котором каждый элемент равен значение * индекс, затем выведите его с помощью implode.
Вывод: PHP-скрипт
Map with the index

Пропуск части результатов

Иногда часть результатов нужно отбросить. Верните для них null, а затем уберите значения null с помощью array_filter. Осторожно: array_filter сохраняет исходные ключи, поэтому у отфильтрованного массива остаются ключи 0 и 2, и json_encode выводит его как {"0":3,"2":9}. array_values переиндексирует его в аккуратный список: [3,9].

Prompt
Преобразуйте массив 1, 2, 3 так, чтобы 2 стало null, а остальные числа были умножены на 3. Уберите null с помощью array_filter и выведите отфильтрованный массив с помощью json_encode, чтобы показать, что исходные ключи сохраняются, затем переиндексируйте его с помощью array_values и выведите ещё раз.
Вывод: PHP-скрипт
Skip some results

Преобразование ключей массива

Чтобы изменить ключи ассоциативного массива, преобразуйте ключи и склейте их обратно со значениями. array_keys даёт все ключи, array_map('strtoupper', ...) переводит их в верхний регистр, а array_combine сопоставляет новые ключи со старыми значениями.

Prompt
Начните с ассоциативного массива из "key1" в 1 и "key2" в 2. Постройте новый массив с теми же значениями, но со всеми ключами в верхнем регистре, используя array_keys, array_map и array_combine. Выведите новый массив с помощью json_encode.
Вывод: PHP-скрипт
Transform array keys

Преобразование значений массива

Чтобы изменить значения, сохраните ключи и вычислите новые значения. array_map умеет проходить по двум массивам одновременно — здесь по ключам и по значениям, — поэтому каждое новое значение равно старому значению плюс длина его ключа: 1 + strlen("key1") даёт 5.

Prompt
Начните с ассоциативного массива из "key1" в 1 и "key2" в 2. Постройте новый массив с теми же ключами, где каждое значение равно старому значению плюс длина его ключа. Выведите новый массив с помощью json_encode.
Вывод: PHP-скрипт
Transform array values

Zip

Zip берёт два массива и сопоставляет их элементы по позиции: первый с первым, второй со вторым и так далее.

В PHP для этого есть классический приём: array_map(null, $a, $b). Когда обратный вызов равен null и передано несколько массивов, array_map строит массив пар. Обратите внимание, что она не останавливается на более коротком массиве — недостающие места заполняются значением null, — поэтому объединяйте массивы одинаковой длины или сначала обрежьте более длинный с помощью array_slice.

Объединение двух массивов

С null в качестве обратного вызова array_map сопоставляет два массива в массив двухэлементных массивов. json_encode показывает весь результат в одну строку.

Prompt
Объедините массивы red, brown, grey и fox, bear, wolf поэлементно в массив пар с помощью array_map с null в качестве обратного вызова. Выведите пары с помощью json_encode.
Вывод: PHP-скрипт
Zip two arrays

Объединение с преобразованием

Сами пары нужны не всегда. Передайте array_map настоящий обратный вызов и оба массива, и она вызовет функцию с одним элементом из каждого. ucfirst переводит первую букву названия животного в верхний регистр.

Prompt
Объедините массивы red, brown, grey и fox, bear, wolf поэлементно с помощью array_map. Для каждой пары постройте предложение вида "The Fox is red", где первая буква животного в верхнем регистре, и выведите по одному предложению на строку.
Вывод: PHP-скрипт
Zip with a transformation

Разделение массива пар

Unzip — обратная операция: один массив пар превращается в два массива. array_column собирает элемент с одной позиции из каждой пары: позиция 0 даёт слова, а позиция 1 — числа.

Prompt
Начните с массива пар: one с 1, two с 2, three с 3. Разделите его на массив слов и массив чисел с помощью array_column и выведите каждый массив на отдельной строке с помощью implode.
Вывод: PHP-скрипт
Unzip an array of pairs

Associate

Associate строит ассоциативный массив из списка. Каждый элемент даёт один ключ и одно значение. Массив не может дважды содержать один и тот же ключ, поэтому, если два элемента дают одинаковый ключ, побеждает последний.

Приём — обычный цикл foreach: начните с пустого массива и для каждого элемента выполните присваивание $result[$key] = $value. PHP сохраняет элементы в том порядке, в котором они были добавлены.

Элементы как ключи

Сам элемент становится ключом, а значение вычисляется из него. Здесь слова — ключи, а их длины — значения, поэтому программа выводит {"one":3,"two":3,"three":5}.

Prompt
Постройте ассоциативный массив из слов one, two, three, где каждое слово — ключ, а его длина — значение. Выведите массив с помощью json_encode.
Вывод: PHP-скрипт
Elements as keys

Элементы как значения

Элемент становится значением, а ключ вычисляется из него. Здесь ключ — первая буква в верхнем регистре, взятая через $word[0] и strtoupper. И two, и three начинаются с T, поэтому three заменяет two и в массиве остаётся только два элемента.

Prompt
Постройте ассоциативный массив из слов one, two, three, где ключ — первая буква слова в верхнем регистре, а значение — само слово. Выведите массив с помощью json_encode и обратите внимание, что «three» заменяет «two» под ключом T.
Вывод: PHP-скрипт
Elements as values

Вычисление и ключа, и значения

Из элемента можно вычислить и ключ, и значение. Здесь ключ — первая буква, а значение — длина слова. Снова побеждает более поздний элемент с ключом T.

Prompt
Постройте ассоциативный массив из слов one, two, three, где ключ — первая буква в верхнем регистре, а значение — длина слова. Выведите массив с помощью json_encode.
Вывод: PHP-скрипт
Compute both key and value

Ключ и значение из одного элемента

Иногда один элемент несёт обе части. explode разбивает полное имя по пробелу в массив слов, а присваивание списку [$first, $last] = ... распаковывает его. Фамилия становится ключом, а имя — значением.

Prompt
Начните с полных имён "Alice Adams" и "Brian Brown". Разбейте каждое имя на слова с помощью explode и постройте ассоциативный массив из фамилии в имя. Выведите массив с помощью json_encode.
Вывод: PHP-скрипт
Key and value from one element

Flatten

Flatten превращает вложенную коллекцию, например массив массивов, в один плоский массив со всеми элементами по порядку.

В PHP array_merge соединяет любое количество массивов, а три точки распаковывают внутренние массивы в вызов: array_merge(...$nested).

Уплощение массива массивов

Три точки превращают array_merge(...$numberSets) в array_merge([1, 2, 3], [4, 5, 6]). Два внутренних массива по три числа становятся одним массивом из шести.

Prompt
Начните с массива массивов: 1, 2, 3 и 4, 5, 6. Сделайте из него один плоский массив с помощью array_merge и оператора ..., затем выведите его с помощью implode.
Вывод: PHP-скрипт
Flatten an array of arrays

Уплощение значений из объектов

Flat map сначала берёт массив из каждого элемента, а затем соединяет все эти массивы вместе. array_map читает свойство $values каждого контейнера, а array_merge с тремя точками склеивает три массива в один.

Prompt
Определите класс Container со свойством-массивом values. Создайте три контейнера, содержащих one, two, three; four, five; и six, seven, eight. Соберите все их значения в один массив с помощью array_map и array_merge и выведите его с помощью implode.
Вывод: PHP-скрипт
Flatten values from objects

Строковое представление

Часто коллекцию нужно показать как читаемый текст, например с запятыми между элементами.

В PHP implode принимает разделитель и массив и возвращает одну строку. Числа превращаются в текст автоматически. Дополнения — префикс, постфикс, ограничение или преобразование — делаются конкатенацией строк, с помощью array_slice или array_map перед соединением.

Соединение с разделителем

implode ставит ", " между словами и возвращает одну строку.

Prompt
Соедините слова one, two, three в одну строку с ", " между ними с помощью implode. Выведите строку.
Вывод: PHP-скрипт
Join with a separator

Добавление префикса и постфикса

Префикс и постфикс — это просто текст вокруг соединённого результата. В PHP их добавляют оператором ..

Prompt
Соедините слова one, two, three с " | " между ними, добавьте префикс "start: " и постфикс ": end" и выведите результат.
Вывод: PHP-скрипт
Add a prefix and a postfix

Ограничение числа элементов

Для длинного массива может понадобиться показать только несколько первых элементов. range(1, 100) строит числа, array_slice($numbers, 0, 10) берёт первые 10, а "...>" добавляется в конец, чтобы показать, что остальные элементы отброшены. implode сам превращает числа в текст.

Prompt
Создайте массив с числами от 1 до 100 с помощью range. Соедините только первые 10 из них через ", ", взяв их с помощью array_slice, и добавьте в конце "<...>", чтобы показать, что список был обрезан. Выведите результат.
Вывод: PHP-скрипт
Limit the number of elements

Преобразование каждого элемента перед соединением

Чтобы изменить каждый элемент перед соединением, сначала преобразуйте массив с помощью array_map, а затем примените implode к результату. Здесь каждое слово становится "Element: " плюс само слово в верхнем регистре.

Prompt
Превратите каждое из слов one, two, three в "Element: " и следующее за ним слово в верхнем регистре с помощью array_map. Соедините результаты через ", " и выведите строку.
Вывод: PHP-скрипт
Transform each element before joining