Как «сгладить» многомерный массив до простого в PHP?

Вероятно, это начальный вопрос, но я уже давно обрабатываю документацию, и я не могу найти какое-либо решение. Я думал, что могу использовать implode для каждого измерения, а затем поместить эти строки обратно вместе с str_split чтобы создать новый простой массив. Однако я никогда не знаю, является ли шаблон объединения не в значениях, поэтому после выполнения str_split мои исходные значения могут сломаться.

Есть ли что-то вроде combine($array1, $array2) для массивов внутри многомерного массива?

Solutions Collecting From Web of "Как «сгладить» многомерный массив до простого в PHP?"

Используйте array_values . (Пример из php-сайта)

 <?php $aNonFlat = array( 1, 2, array( 3, 4, 5, array( 6, 7 ), 8, 9, ), 10, 11 ); $objTmp = (object) array('aFlat' => array()); array_walk_recursive($aNonFlat, create_function('&$v, $k, &$t', '$t->aFlat[] = $v;'), $objTmp); var_dump($objTmp->aFlat); /* array(11) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) [6]=> int(7) [7]=> int(8) [8]=> int(9) [9]=> int(10) [10]=> int(11) } */ ?> 
 $array = your array $result = call_user_func_array('array_merge', $array); echo "<pre>"; print_r($result); 

REF: http://php.net/manual/en/function.call-user-func-array.php

Вот еще одно решение (работает с многомерным массивом):

 function array_flatten($array) { $return = array(); foreach ($array as $key => $value) { if (is_array($value)){ $return = array_merge($return, array_flatten($value));} else {$return[$key] = $value;} } return $return; } $array = Your array $result = array_flatten($array); echo "<pre>"; print_r($result); 

Это одна линия, SUPER проста в использовании:

 $result = array(); array_walk_recursive($original_array,function($v, $k) use (&$result){ $result[] = $v; }); 

Очень легко понять, внутри анонимной функции / закрытия $ v – это значение, а $ k – это ключ вашего исходного массива.

 // $array = your multidimensional array $flat_array = array(); foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v){ $flat_array[$k] = $v; } 

Также документально подтверждено: http://www.phpro.org/examples/Flatten-Array.html

 function flatten_array($array, $preserve_keys = 0, &$out = array()) { # Flatten a multidimensional array to one dimension, optionally preserving keys. # # $array - the array to flatten # $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys # $out - internal use argument for recursion foreach($array as $key => $child) if(is_array($child)) $out = flatten_array($child, $preserve_keys, $out); elseif($preserve_keys + is_string($key) > 1) $out[$key] = $child; else $out[] = $child; return $out; } 

Другой метод из комментариев пользователя PHP (упрощенный) и здесь :

 function array_flatten_recursive($array) { if (!$array) return false; $flat = array(); $RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array)); foreach ($RII as $value) $flat[] = $value; return $flat; } 

Большим преимуществом этого метода является то, что он отслеживает глубину рекурсии, если вам нужно это при выравнивании.
Это приведет к выводу:

 $array = array( 'A' => array('B' => array( 1, 2, 3)), 'C' => array(4, 5) ); print_r(array_flatten_recursive($array)); #Returns: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 ) 

В PHP> = 5.3 и на основе ответа Люка М (первого) вы можете использовать блокировки, подобные этому

 array_walk_recursive($aNonFlat, function(&$v, $k, &$t){$t->aFlat[] = $v;}, $objTmp); 

Мне это нравится, потому что мне не нужно окружать код функции кавычками, как при использовании create_function ()

Нерекурсивное решение (но уничтожение порядка):

 function flatten($ar) { $toflat = array($ar); $res = array(); while (($r = array_shift($toflat)) !== NULL) { foreach ($r as $v) { if (is_array($v)) { $toflat[] = $v; } else { $res[] = $v; } } } return $res; } 

С PHP 7 вы можете использовать генераторы и генераторное делегирование ( yield from ) для выравнивания массива:

 function array_flatten_iterator (array $array) { foreach ($array as $value) { if (is_array($value)) { yield from array_flatten_iterator($value); } else { yield $value; } } } function array_flatten (array $array) { return iterator_to_array(array_flatten_iterator($array), false); } 

Пример:

 $array = [ 1, 2, [ 3, 4, 5, [ 6, 7 ], 8, 9, ], 10, 11, ]; var_dump(array_flatten($array)); 

http://3v4l.org/RU30W

Использование функций более высокого порядка (примечание: я использую встроенные анонимные функции , которые появились в PHP 5.3):

 function array_flatten($array) { return array_reduce( $array, function($prev, $element) { if (!is_array($element)) $prev[] = $element; else $prev = array_merge($prev, array_flatten($element)); return $prev; }, array() ); } 

Новый подход, основанный на предыдущей функции, представленной хаосом, которая исправляет ошибку перезаписи строковых ключей в multarrays:

 # Flatten a multidimensional array to one dimension, optionally preserving keys. # $array - the array to flatten # $preserve_keys - 0 (default) to not preserve keys, 1 to preserve string keys only, 2 to preserve all keys # $out - internal use argument for recursion function flatten_array($array, $preserve_keys = 2, &$out = array(), &$last_subarray_found) { foreach($array as $key => $child) { if(is_array($child)) { $last_subarray_found = $key; $out = flatten_array($child, $preserve_keys, $out, $last_subarray_found); } elseif($preserve_keys + is_string($key) > 1) { if ($last_subarray_found) { $sfinal_key_value = $last_subarray_found . "_" . $key; } else { $sfinal_key_value = $key; } $out[$sfinal_key_value] = $child; } else { $out[] = $child; } } return $out; } Example: $newarraytest = array(); $last_subarray_found = ""; $this->flatten_array($array, 2, $newarraytest, $last_subarray_found); 
 /*consider $mArray as multidimensional array and $sArray as single dimensional array this code will ignore the parent array */ function flatten_array2($mArray) { $sArray = array(); foreach ($mArray as $row) { if ( !(is_array($row)) ) { if($sArray[] = $row){ } } else { $sArray = array_merge($sArray,flatten_array2($row)); } } return $sArray; } 

вы можете попробовать следующее:

 function flat_an_array($a) { foreach($a as $i) { if(is_array($i)) { if($na) $na = array_merge($na,flat_an_array($i)); else $na = flat_an_array($i); } else $na[] = $i; } return $na; } 

Если вы справитесь с потерями ключей массива, вы можете сгладить многомерный массив, используя рекурсивное закрытие в качестве обратного вызова, который использует array_values ​​(), убедившись, что этот обратный вызов является параметром для array_walk (), следующим образом.

 <?php $array = [1,2,3,[5,6,7]]; $nu_array = null; $callback = function ( $item ) use(&$callback, &$nu_array) { if (!is_array($item)) { $nu_array[] = $item; } else if ( is_array( $item ) ) { foreach( array_values($item) as $v) { if ( !(is_array($v))) { $nu_array[] = $v; } else { $callback( $v ); continue; } } } }; array_walk($array, $callback); print_r($nu_array); 

Единственным недостатком предыдущего примера является то, что он включает в себя гораздо больше кода, чем следующее решение, которое использует array_walk_recursive () вместе с упрощенным обратным вызовом:

 <?php $array = [1,2,3,[5,6,7]]; $nu_array = []; array_walk_recursive($array, function ( $item ) use(&$nu_array ) { $nu_array[] = $item; } ); print_r($nu_array); 

Просмотреть код в реальном времени

Этот пример кажется предпочтительным для предыдущего, скрывая детали о том, как значения извлекаются из многомерного массива. Разумеется, итерация происходит, но имеет ли она рекурсию или структуру управления, вы будете знать только из perusing array.c . Поскольку функциональное программирование фокусируется на вводных и выходных данных, а не на мелочи получения результата, безусловно, можно не беспокоиться о том, как происходит итерация за кадром, то есть до тех пор, пока перспективный работодатель не поставит такой вопрос.

Если вас интересуют только значения для одного конкретного ключа, вы можете найти этот подход полезным:

 function valuelist($array, $array_column) { $return = array(); foreach($array AS $row){ $return[]=$row[$array_column]; }; return $return; }; 

Пример:

Учитывая $ get_role_action =

 array(3) { [0]=> array(2) { ["ACTION_CD"]=> string(12) "ADD_DOCUMENT" ["ACTION_REASON"]=> NULL } [1]=> array(2) { ["ACTION_CD"]=> string(13) "LINK_DOCUMENT" ["ACTION_REASON"]=> NULL } [2]=> array(2) { ["ACTION_CD"]=> string(15) "UNLINK_DOCUMENT" ["ACTION_REASON"]=> NULL } } 

чем $variables['role_action_list']=valuelist($get_role_action, 'ACTION_CD'); приведет к:

 $variables["role_action_list"]=> array(3) { [0]=> string(12) "ADD_DOCUMENT" [1]=> string(13) "LINK_DOCUMENT" [2]=> string(15) "UNLINK_DOCUMENT" } 

Оттуда вы можете выполнять поиск значений так:

 if( in_array('ADD_DOCUMENT', $variables['role_action_list']) ){ //do something }; 

любое из этого не работало для меня … поэтому пришлось запускать его сам. отлично работает:

 function arrayFlat($arr){ $out = ''; foreach($arr as $key => $value){ if(!is_array($value)){ $out .= $value.','; }else{ $out .= $key.','; $out .= arrayFlat($value); } } return trim($out,','); } $result = explode(',',arrayFlat($yourArray)); echo '<pre>'; print_r($result); echo '</pre>'; 

Учитывая многомерный массив и преобразование его в одномерный, можно сделать, отключив все значения, которые имеют массивы и сохраняют их в первом измерении, например:

 function _flatten_array($arr) { while ($arr) { list($key, $value) = each($arr); is_array($value) ? $arr = $value : $out[$key] = $value; unset($arr[$key]); } return (array)$out; } с function _flatten_array($arr) { while ($arr) { list($key, $value) = each($arr); is_array($value) ? $arr = $value : $out[$key] = $value; unset($arr[$key]); } return (array)$out; } 

Вы можете использовать функцию сглаживания из нестандартной библиотеки PHP (NSPL) . Он работает с массивами и любыми итерабельными структурами данных.

 assert([1, 2, 3, 4, 5, 6, 7, 8, 9] === flatten([[1, [2, [3]]], [[[4, 5, 6]]], 7, 8, [9]])); 

Простой подход. Посмотрите на него через рекурсию.

 <?php function flatten_array($simple){ static $outputs=array(); foreach ( $simple as $value) { if(is_array($value)){ flatten_array($value); } else{ $outputs[]=$value; } } return $outputs; } $eg=['s'=>['p','n'=>['t']]]; $out=flatten_array($eg); print_r($out); ?> , <?php function flatten_array($simple){ static $outputs=array(); foreach ( $simple as $value) { if(is_array($value)){ flatten_array($value); } else{ $outputs[]=$value; } } return $outputs; } $eg=['s'=>['p','n'=>['t']]]; $out=flatten_array($eg); print_r($out); ?>