Можно ли в PHP сгладить (двух- или многомерный) массив без использования рекурсии или ссылок?
Меня интересуют только значения, так что ключи можно игнорировать, я думаю, в строках array_map()
и array_values()
.
php
arrays
multidimensional-array
flatten
Аликс Аксель
источник
источник
Ответы:
Вы можете использовать стандартную библиотеку PHP (SPL), чтобы «скрыть» рекурсию.
печать
источник
iterator_to_array($it, false)
избегает необходимости в foreach.function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }
надеюсь, это поможет другим.Начиная с PHP 5.3, самое короткое решение кажется
array_walk_recursive()
с новым синтаксисом замыканий:источник
use
синтаксис для этой работы,array_walk_recursive
поскольку он не будет принимать необязательный$userdata
параметр по ссылкеРешение для двумерного массива
Пожалуйста, попробуйте это:
РЕДАКТИРОВАТЬ: 21 августа 13
Вот решение, которое работает для многомерного массива:
Ссылка: http://php.net/manual/en/function.call-user-func-array.php
источник
call_user_func_array('array_merge', [])
(обратите внимание на пустой массив) возвращает ноль и вызывает предупреждение об ошибке php. Это отличное решение, если вы точно знаете, что ваш массив не будет пустым, но многие не могут этого сделать.$result = $array ?call_user_func_array('array_merge', $array) : [];
В PHP 5.6 и выше вы можете сгладить двумерные массивы с помощью
array_merge
после распаковки внешнего массива с помощью...
оператора. Код прост и понятен.Это работает и с коллекцией ассоциативных массивов.
Но это не работает, когда внешний массив имеет не числовые ключи. В этом случае вам придется
array_values
сначала позвонить .Обновление: на основе комментария @MohamedGharib
Это выдаст ошибку, если внешний массив пуст, так как
array_merge
будет вызван с нулевыми аргументами. Этого можно избежать, добавив пустой массив в качестве первого аргумента.источник
array_merge([], ...$a);
Чтобы сгладить без рекурсии (как вы просили), вы можете использовать стек . Естественно, вы можете поместить это в функцию своего собственного как
array_flatten
. Ниже приведена версия, которая работает без ключей:Элементы обрабатываются в их порядке. Поскольку подэлементы будут перемещены поверх стека, они будут обработаны следующим.
Также можно принять во внимание ключи, однако вам потребуется другая стратегия для обработки стека. Это необходимо, потому что вам нужно иметь дело с возможными дублирующимися ключами в подмассивах. Аналогичный ответ в связанном вопросе: PHP пройти через многомерный массив при сохранении ключей
Я не совсем уверен, но я проверял это в прошлом:
RecurisiveIterator
он использует рекурсию, так что это зависит от того, что вам действительно нужно. Должна быть возможность создать рекурсивный итератор также на основе стеков:демонстрация
Я не делал этого до сих пор, чтобы реализовать стек, на
RecursiveIterator
котором, я думаю, это хорошая идея.источник
if(!empty($value)){$flat[] = $value}
внутри оператора else, чтобы предотвратить добавление пустого в массив результатов. Потрясающая функция!Простой и однострочный ответ.
Использование:
Выход (в PsySH):
Теперь вам решать, как вы будете обращаться с ключами. ура
РЕДАКТИРОВАТЬ (2017-03-01)
Цитируя озабоченность / проблему Найджела Алдертона :
Цитирование Svish ответа «S:
источник
$array = ['a',['b','c']]
становитсяArray ([0] => b, [1] => c )
. Это'a'
потеряно, потому что'b'
также имеет ключ0
.false
качестве второго параметра ($use_keys
) кiterator_to_array
вызову.Использует рекурсию. Надеюсь, увидев, насколько он не сложный, ваш страх рекурсии рассеется, как только вы увидите, насколько он не сложен.
Вывод:
источник
Просто подумал, что укажу, что это фолд, поэтому можно использовать array_reduce:
РЕДАКТИРОВАТЬ: Обратите внимание, что это может быть составлено, чтобы сгладить любое количество уровней. Мы можем сделать это несколькими способами:
Конечно, мы могли бы также использовать циклы, но вопрос требует использования комбинаторной функции в соответствии с array_map или array_values.
источник
fold
его на 4 уровня, илиfold . fold
получить 3 уровня, илиfold . fold . fold
2 уровня и т. д. Это также предотвращает скрытие ошибок; например. если я хочу сгладить массив 5D, но мне дан массив 4D, ошибка немедленно сработает.$concat
, я думаю, вы должны просто назвать это$flatten
.array_merge
является php-эквивалентом concat. Я пытался получитьarray_concat
добавлен в качестве псевдонимаarray_merge
.Выравнивает только двухмерные массивы:
источник
Это решение не является рекурсивным. Обратите внимание, что порядок элементов будет несколько смешанным.
источник
shifting
значение из массива и добавление его в конец не имеет особого смысла. Я думаю, что вы хотелиarray_merge()
вместо этого?Я считаю, что это самое чистое решение без использования каких-либо мутаций или незнакомых классов.
источник
Попробуйте следующую простую функцию:
Итак, из этого:
ты получаешь:
источник
Хитрость заключается в передаче массива источника и назначения по ссылке.
источник
Фрагмент Gist
источник
Вы можете сделать это с вкусностями Узо :
Смотрите: здесь
источник
Если вам действительно не нравится рекурсия ... попробуйте вместо этого переключиться :)
Примечание: в этой простой версии это не поддерживает ключи массива.
источник
continue
, это несколько быстрее.Как насчет использования рекурсивного генератора? https://ideone.com/d0TXCg
источник
Для PHP 5.2
источник
Эта версия может делать глубокие, мелкие или определенное количество уровней:
источник
Потому что код здесь выглядит страшно. Вот функция, которая также преобразует многомерный массив в синтаксис, совместимый с HTML-формой, но который легче читать.
источник
Это может быть достигнуто с помощью
array_walk_recursive
Рабочий пример: - https://3v4l.org/FpIrG
источник
Это мое решение, используя ссылку:
источник
источник
Вот упрощенный подход:
источник
Любой, кто ищет действительно чистое решение для этого; вот вариант:
Печать
источник
Просто выкладываю еще какое-то решение)
источник
Если вы хотите сохранить ваши ключи, это решение.
К сожалению, он выводит только окончательные вложенные массивы без средних клавиш. Итак, для следующего примера:
Выход:
источник
Мне нужно было представить многомерный массив PHP в формате ввода HTML.
источник
$var['a']['b']['c'][0] = 'a'; ...
.Если у вас есть массив объектов и вы хотите сгладить его с помощью узла, просто используйте эту функцию:
источник