php array map with keys
PHP: array_map и ключи массива
Записная книжка рассеянного [в пространстве и времени] программиста
PHP: array_map и ключи массива
Интересно, почему такой вопрос часто всплывает на форумах или где-то еще?
Сначала постараюсь ответить на вопрос “нафига?”, а потом на вопрос “как?”.
Мы привыкли, что в в питоне, js и множестве других языков и фреймворков есть функция map, которая применяет некоторую функцию-обработчик к каждому элементу в списке данных и возвращающую результат в том же порядке. Пруф.
Но никто не ждал, что хеш-таблица и массив в контексте одного из языков будет означать одно и то же. Опять же пруф.
Этот постыдный момент из жизни структуры привел к тому, что одним из самых частых применений массивов (в пхп конечно же) стало создание отображений категория=>какое-то значение.
А после того как у вас появилось отображение вы, вероятно, захотите это где-нибудь на сгенерированной странице отобразить.
Т.е. показать пользователю сам параметр, а скобках его категорию.
Как мы делаем это в языках (фреймворках), которые разделяют понятие массива и хеш-таблицы? Перебираем объект, который содержит категории и формируем по нему массив выводимых данных. Наверное так.
И тут мы открываем руководство по php и видим, что она применяет некий колбек ко всем элементам массива и после этого возвращает новый массив.
Удобно же! Применили колбек к массиву и получили обработанный.
И что-то не заладилось. 🙂 Ключи в колбек не попадают. Можно сделать все через foreach, но тогда нам потребуется еще одна переменная. А тут все было просто и наглядно.
И мы идем в гугель: “php array_map with keys”.
И все отлично работает. И притом правильно. Относительно конечно же. И никаких вам лишних переменных.
А тем временем в коде вновь и вновь появляются конструкции вида
Проблема кейса из статьи может быть и раздута, но при вчитывании в сотни строк кода более-менее понятными сходу являются только первые два варианта.
(PHP 4 >= 4.0.6, PHP 5, PHP 7)
array_map — Применяет callback-функцию ко всем элементам указанных массивов
Описание
Список параметров
Callback-функция, применяемая к каждому элементу в каждом массиве.
Возвращаемые значения
Примеры
Пример #1 Пример использования array_map()
Пример #2 Использование array_map() вместе с lambda-функцией (начиная с версии PHP 5.3.0)
Пример #3 Пример использования array_map() : обработка нескольких массивов
Результат выполнения данного примера:
Обычно при обработке двух или более массивов, они имеют одинаковую длину, так как callback-функция применяется параллельно к соответствующим элементам массивов. Если массивы имеют различную длину, более короткие из них дополняется элементами с пустыми значениями до длины самого длинного массива.
Интересным эффектом при использовании этой функции является создание массива массивов, что может быть достигнуто путем использования значения NULL в качестве имени callback-функции.
Пример #4 Создание массива массивов
Результат выполнения данного примера:
Если массив-аргумент содержит строковые ключи, то результирующий массив будет содержать строковые ключи тогда и только тогда, если передан ровно один массив. Если передано больше одного аргумента, то результирующий массив будет всегда содержать числовые ключи.
Пример #5 Использование array_map() со строковыми ключами
Результат выполнения данного примера:
Смотрите также
array_map
(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)
array_map — Применяет callback-функцию ко всем элементам указанных массивов
Описание
Список параметров
Возвращаемые значения
Возвращённый массив сохранит ключи аргумента массива тогда и только тогда, когда будет передан ровно один массив. Если передано более одного массива, возвращённый массив будет иметь последовательные целочисленные ключи.
Примеры
Пример #1 Пример использования array_map()
Пример #2 Использование array_map() вместе с лямбда-функцией
Пример #3 Пример использования array_map() : обработка нескольких массивов
Результат выполнения данного примера:
Обычно при обработке двух или более массивов, они имеют одинаковую длину, так как callback-функция применяется параллельно к соответствующим элементам массивов. Если массивы имеют различную длину, более короткие из них дополняется элементами с пустыми значениями до длины самого длинного массива.
Интересным эффектом при использовании этой функции является создание массива массивов, что может быть достигнуто путём использования значения null в качестве имени callback-функции.
Пример #4 Выполнение zip операции с массивами
Результат выполнения данного примера:
Пример #5 null callback только с array
Результат выполнения данного примера:
Пример #6 Использование array_map() со строковыми ключами
Результат выполнения данного примера:
Результат выполнения данного примера:
Смотрите также
User Contributed Notes 6 notes
Let’s assume we have following situation:
You may be looking for a method to extract values of a multidimensional array on a conditional basis (i.e. a mixture between array_map and array_filter) other than a for/foreach loop. If so, you can take advantage of the fact that 1) the callback method on array_map returns null if no explicit return value is specified (as with everything else) and 2) array_filter with no arguments removes falsy values.
So for example, provided you have:
To transpose rectangular two-dimension array, use the following code:
If you need to rotate rectangular two-dimension array on 90 degree, add the following line before or after (depending on the rotation direction you need) the code above:
$array = array_reverse($array);
PHP’s array_map including keys
Is there a way of doing something like this:
The desired output is:
18 Answers 18
Not with array_map, as it doesn’t handle keys.
It does change the array given as parameter however, so it’s not exactly functional programming (as you have the question tagged like that). Also, as pointed out in the comment, this will only change the values of the array, so the keys won’t be what you specified in the question.
You could write a function that fixes the points above yourself if you wanted to, like this:
This is probably the shortest and easiest to reason about:
Here’s my very simple, PHP 5.5-compatible solution:
Usage
Output
Partial application
In case you need to use the function many times with different arrays but the same mapping function, you can do something called partial function application (related to ‘currying’), which allows you to only pass in the data array upon invocation:
NOTE: if your mapped function returns the same key for two different inputs, the value associated with the later key will win. Reverse the input array and output result of array_map_assoc to allow earlier keys to win. (The returned keys in my example cannot collide as they incorporate the key of the source array, which in turn must be unique.)
Alternative
Following is a variant of the above, which might prove more logical to some, but requires PHP 5.6:
n.b. Alex83690 has noted in a comment that using array_replace here in the stead of array_merge would preserve integer keys. array_replace does not modify the input array, so is safe for functional code.
If you are on PHP 5.3 to 5.5, the following is equivalent. It uses array_reduce and the binary + array operator to convert the resulting two-dimensional array down to a one-dimensional array whilst preserving keys:
Usage
Both of these variants would be used thus:
The output is the same as before, and each can be partially applied in the same way as before.
Summary
The goal of the original question is to make the invocation of the call as simple as possible, at the expense of having a more complicated function that gets invoked; especially, to have the ability to pass the data array in as a single argument, without splitting the keys and values. Using the function supplied at the start of this answer:
Or, for this question only, we can make a simplification to array_map_assoc() function that drops output keys, since the question does not ask for them:
With PHP5.3 or later:
Look here! There is a trivial solution!
As stated in the question, array_map already has exactly the functionality required. The other answers here seriously overcomplicate things: array_walk is not functional.
Usage
Exactly as you would expect from your example:
I’ll add yet another solution to the problem using version 5.6 or later. Don’t know if it’s more efficient than the already great solutions (probably not), but to me it’s just simpler to read:
Hopefully I’m not the only one who finds this pretty simple to grasp. array_combine creates a key => value array from an array of keys and an array of values, the rest is pretty self explanatory.
Your technique using array_map with array_keys though actually seems simpler and is more powerful because you can use null as a callback to return the key-value pairs:
This is how I’ve implemented this in my project.
Based on eis’s answer, here’s what I eventually did in order to avoid messing the original array:
I made this function, based on eis’s answer:
Off course, you can use array_values to return exactly what OP wants.
I always like the javascript variant of array map. The most simple version of it would be:
So now you can just pass it a callback function how to construct the values.
I’d do something like this:
You can use map method from this array library to achieve exactly what you want as easily as:
also it preserves keys and returns new array, not to mention few different modes to fit your needs.
Another way of doing this with(out) preserving keys:
A closure would work if you only need it once. I’d use a generator.
For something reusable:
I see it’s missing the obvious answer:
Works exactly like array_map. Almost.
Actually, it’s not pure map as you know it from other languages. Php is very weird, so it requires some very weird user functions, for we don’t want to unbreak our precisely broken worse is better approach.
Really, it’s not actually map at all. Yet, it’s still very useful.
First obvious difference from array_map, is that the callback takes outputs of each() from every input array instead of value alone. You can still iterate through more arrays at once.
Any other elements except those with keys 0 and 1 in callback’s return are ignored.
And finally, if lambda returns any value except of null or array, it’s treated as if both key and value were omitted, so:
WARNING:
Bear in mind, that this last feature is just a residue of previous features and it is probably completely useless. Relying on this feature is highly discouraged, as this feature is going to be randomly deprecated and changed unexpectedly in future releases.
Php array map with keys
Описание array array_map ( mixed callback, array array1 [, array array2. ] )
Пример 1. Пример использования array_map()
Array ( [0] => 1 [1] => 8 [2] => 27 [3] => 64 [4] => 125 )
Пример 2. Пример использования array_map() : обработка нескольких массивов
$a = array(1, 2, 3, 4, 5);
$b = array(«uno», «dos», «tres», «cuatro», «cinco»);
Результат выполнения:
$a = array(1, 2, 3, 4, 5); $b = array(«one», «two», «three», «four», «five»); $c = array(«uno», «dos», «tres», «cuatro», «cinco»); Результатом выполнения вышеприведенной программы будет: |