다차원 배열을 단순화하는 방법?
PHP다차원 배열을 단순화하는 방법?
재귀 또는 참조를 사용하지 않고 (쌍 / 다중) 차원 배열을 병합하는 것이 PHP에서 가능합니까?
키가 무시 될 수 있도록 값에만 관심이 있습니다. array_map () 및 array_values () 행에서 생각하고 있습니다.
해결법
-
==============================
1.
표준 PHP 라이브러리 (SPL)를 사용하여 재귀를 숨길 수 있습니다.
$a = array(1,2,array(3,4, array(5,6,7), 8), 9); $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($a)); foreach($it as $v) { echo $v, " "; }
인쇄물
1 2 3 4 5 6 7 8 9
-
==============================
2.
PHP 5.3에서 가장 짧은 해결책은 새로운 closure 구문을 가진 array_walk_recursive () 인 것 같습니다 :
function flatten(array $array) { $return = array(); array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; }); return $return; }
-
==============================
3.
2 차원 배열 솔루션
이것을 시도하십시오 :
$array = your array $result = call_user_func_array('array_merge', $array); echo "<pre>"; print_r($result);
편집 : 21-8 월 -13
다음은 다차원 배열에서 작동하는 솔루션입니다.
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);
참조 : http://php.net/manual/en/function.call-user-func-array.php
-
==============================
4.
w / o 재귀를 평평하게하려면 (요청한대로) 스택을 사용할 수 있습니다. 당연히 array_flatten과 같은 자신의 함수에 넣을 수 있습니다. 다음은 w / o 키가 작동하는 버전입니다.
function array_flatten(array $array) { $flat = array(); // initialize return array $stack = array_values($array); // initialize stack while($stack) // process stack until done { $value = array_shift($stack); if (is_array($value)) // a value to further process { $stack = array_merge(array_values($value), $stack); } else // a value to take { $flat[] = $value; } } return $flat; }
요소는 순서대로 처리됩니다. 하위 요소가 스택 맨 위로 이동되므로 하위 요소가 다음으로 처리됩니다.
키를 고려하는 것도 가능하지만 스택을 처리하는 데는 다른 전략이 필요합니다. 하위 배열에서 가능한 중복 키를 처리해야하므로 필요합니다. 관련 질문에서 비슷한 대답 : PHP 키를 보존하면서 다차원 배열을 따라 가라.
확실하지는 않지만 과거에 이것을 테스트했습니다. RecurisiveIterator는 재귀를 사용하므로 실제로 필요한 항목에 따라 다릅니다. 스택을 기반으로 재귀 적 반복자를 생성 할 수 있어야합니다.
foreach(new FlatRecursiveArrayIterator($array) as $key => $value) { echo "** ($key) $value\n"; }
데모
나는 지금까지 그것을 만들지 않았다. 좋은 아이디어라고 생각되는 RecursiveIterator를 기반으로 스택을 구현했다.
-
==============================
5.
재귀를 사용합니다. 다행스럽지 않은 방법을 보면서 바라는대로 복잡성이 얼마나 복잡한지를 알게되면 재귀에 대한 두려움이 사라질 것입니다.
function flatten($array) { if (!is_array($array)) { // nothing to do if it's not an array return array($array); } $result = array(); foreach ($array as $value) { // explode the sub-array, and add the parts $result = array_merge($result, flatten($value)); } return $result; } $arr = array('foo', array('nobody', 'expects', array('another', 'level'), 'the', 'Spanish', 'Inquisition'), 'bar'); echo '<ul>'; foreach (flatten($arr) as $value) { echo '<li>', $value, '</li>'; } echo '<ul>';
산출:
<ul><li>foo</li><li>nobody</li><li>expects</li><li>another</li><li>level</li><li>the</li><li>Spanish</li><li>Inquisition</li><li>bar</li><ul>
-
==============================
6.
그냥 이것이 fold라고 지적 했으므로 array_reduce를 사용할 수 있습니다.
array_reduce($my_array, 'array_merge', array());
편집 :이 수준의 수를 평평하게 구성 할 수 있습니다. 우리는 여러 가지 방법으로 이것을 할 수 있습니다 :
// Reduces one level $concat = function($x) { return array_reduce($x, 'array_merge', array()); }; // We can compose $concat with itself $n times, then apply it to $x // This can overflow the stack for large $n $compose = function($f, $g) { return function($x) use ($f, $g) { return $f($g($x)); }; }; $identity = function($x) { return $x; }; $flattenA = function($n) use ($compose, $identity, $concat) { return function($x) use ($compose, $identity, $concat, $n) { return ($n === 0)? $x : call_user_func(array_reduce(array_fill(0, $n, $concat), $compose, $identity), $x); }; }; // We can iteratively apply $concat to $x, $n times $uncurriedFlip = function($f) { return function($a, $b) use ($f) { return $f($b, $a); }; }; $iterate = function($f) use ($uncurriedFlip) { return function($n) use ($uncurriedFlip, $f) { return function($x) use ($uncurriedFlip, $f, $n) { return ($n === 0)? $x : array_reduce(array_fill(0, $n, $f), $uncurriedFlip('call_user_func'), $x); }; }; }; $flattenB = $iterate($concat); // Example usage: $apply = function($f, $x) { return $f($x); }; $curriedFlip = function($f) { return function($a) use ($f) { return function($b) use ($f, $a) { return $f($b, $a); }; }; }; var_dump( array_map( call_user_func($curriedFlip($apply), array(array(array('A', 'B', 'C'), array('D')), array(array(), array('E')))), array($flattenA(2), $flattenB(2))));
물론 루프를 사용할 수도 있지만 array_map 또는 array_values 행을 따라 결합 함수를 요청합니다.
-
==============================
7.
간단하고 단 하나의 대답.
function flatten_array(array $array) { return iterator_to_array( new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array))); }
용법:
$array = [ 'name' => 'Allen Linatoc', 'profile' => [ 'age' => 21, 'favourite_games' => [ 'Call of Duty', 'Titanfall', 'Far Cry' ] ] ]; print_r( flatten_array($array) );
출력 (PsySH 단위) :
Array ( [name] => Allen Linatoc [age] => 21 [0] => Call of Duty [1] => Titanfall [2] => Far Cry )
이제는 열쇠를 어떻게 다루는 지 당신에게 달려 있습니다. 건배
수정 (2017-03-01)
Nigel Alderton의 우려 / 문제 인용 :
인용 Svish의 대답 :
-
==============================
8.
PHP 5.6 이상에서는 ... 연산자를 사용하여 외부 배열을 압축 해제 한 후 array_merge로 2 차원 배열을 병합 할 수 있습니다. 코드는 간단하고 명확합니다.
$a = [[10, 20], [30, 40]]; $b = [["x" => "X", "y" => "Y"], ["p" => "P", "q" => "Q"]]; print_r(array_merge(...$a)); print_r(array_merge(...$b)); Array ( [0] => 10 [1] => 20 [2] => 30 [3] => 40 ) Array ( [x] => X [y] => Y [p] => P [q] => Q )
그러나 외부 배열에 숫자가 아닌 키가있을 때는 작동하지 않습니다. 이 경우 먼저 array_values를 호출해야합니다.
$c = ["a" => ["x" => "X", "y" => "Y"], "b" => ["p" => "P", "q" => "Q"]]; print_r(array_merge(...array_values($c))); Array ( [x] => X [y] => Y [p] => P [q] => Q )
-
==============================
9.
2 차원 배열 만 평평하게 만듭니다.
$arr = [1, 2, [3, 4]]; $arr = array_reduce($arr, function ($a, $b) { return array_merge($a, (array) $b); }, []); // Result: [1, 2, 3, 4]
-
==============================
10.
이 솔루션은 비 재귀 적입니다. 요소의 순서는 다소 섞여 있음에 유의하십시오.
function flatten($array) { $return = array(); while(count($array)) { $value = array_shift($array); if(is_array($value)) foreach($value as $sub) $array[] = $sub; else $return[] = $value; } return $return; }
-
==============================
11.
다음과 같은 간단한 기능을 시도해보십시오.
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; }
그래서 이것으로부터 :
array ( 'und' => array ( 'profiles' => array ( 0 => array ( 'commerce_customer_address' => array ( 'und' => array ( 0 => array ( 'first_name' => 'First name', 'last_name' => 'Last name', 'thoroughfare' => 'Address 1', 'premise' => 'Address 2', 'locality' => 'Town/City', 'administrative_area' => 'County', 'postal_code' => 'Postcode', ), ), ), ), ), ), )
당신은 얻는다 :
array ( 'first_name' => 'First name', 'last_name' => 'Last name', 'thoroughfare' => 'Address 1', 'premise' => 'Address 2', 'locality' => 'Town/City', 'administrative_area' => 'County', 'postal_code' => 'Postcode', )
-
==============================
12.
나는 이것이 어떤 돌연변이 나 익숙하지 않은 클래스를 사용하지 않고 가장 깨끗한 해결책이라고 생각한다.
<?php function flatten($array) { return array_reduce($array, function($acc, $item){ return array_merge($acc, is_array($item) ? flatten($item) : [$item]); }, []); } // usage $array = [1, 2, [3, 4], [5, [6, 7]], 8, 9, 10]; print_r(flatten($array));
-
==============================
13.
트릭은 원본 및 대상 배열을 모두 참조로 전달합니다.
function flatten_array(&$arr, &$dst) { if(!isset($dst) || !is_array($dst)) { $dst = array(); } if(!is_array($arr)) { $dst[] = $arr; } else { foreach($arr as &$subject) { flatten_array($subject, $dst); } } } $recursive = array('1', array('2','3',array('4',array('5','6')),'7',array(array(array('8'),'9'),'10'))); echo "Recursive: \r\n"; print_r($recursive); $flat = null; flatten_array($recursive, $flat); echo "Flat: \r\n"; print_r($flat); // If you change line 3 to $dst[] = &$arr; , you won't waste memory, // since all you're doing is copying references, and imploding the array // into a string will be both memory efficient and fast:) echo "String:\r\n"; echo implode(',',$flat);
-
==============================
14.
/** * For merging values of a multidimensional array into one * * $array = [ * 0 => [ * 0 => 'a1', * 1 => 'b1', * 2 => 'c1', * 3 => 'd1' * ], * 1 => [ * 0 => 'a2', * 1 => 'b2', * 2 => 'c2', * ] * ]; * * becomes : * * $array = [ * 0 => 'a1', * 1 => 'b1', * 2 => 'c1', * 3 => 'd1', * 4 => 'a2', * 5 => 'b2', * 6 => 'c2', * * ] */ array_reduce ( $multiArray , function ($lastItem, $currentItem) { $lastItem = $lastItem ?: array(); return array_merge($lastItem, array_values($currentItem)); } );
요령
-
==============================
15.
당신은 ouzo 케이크로 그것을 할 수 있습니다 :
$result = Arrays::flatten($multidimensional);
여기를 보아라
-
==============================
16.
정말로 재귀가 마음에 들지 않는다면 대신 시도해보십시오 :)
$a = array(1,2,array(3,4, array(5,6,7), 8), 9); $o = []; for ($i=0; $i<count($a); $i++) { if (is_array($a[$i])) { array_splice($a, $i+1, 0, $a[$i]); } else { $o[] = $a[$i]; } }
참고 :이 간단한 버전에서는 배열 키를 지원하지 않습니다.
-
==============================
17.
PHP 5.2
function flatten(array $array) { $result = array(); if (is_array($array)) { foreach ($array as $k => $v) { if (is_array($v)) { $result = array_merge($result, flatten($v)); } else { $result[] = $v; } } } return $result; }
-
==============================
18.
이 버전은 깊이, 얕은 또는 특정 수의 수준을 수행 할 수 있습니다.
/** * @param array|object $array array of mixed values to flatten * @param int|boolean $level 0:deep, 1:shallow, 2:2 levels, 3... * @return array */ function flatten($array, $level = 0) { $level = (int) $level; $result = array(); foreach ($array as $i => $v) { if (0 <= $level && is_array($v)) { $v = flatten($v, $level > 1 ? $level - 1 : 0 - $level); $result = array_merge($result, $v); } elseif (is_int($i)) { $result[] = $v; } else { $result[$i] = $v; } } return $result; }
-
==============================
19.
여기에있는 코드는 무서운 것처럼 보입니다. 다차원 배열을 html 형식과 호환되는 구문으로 변환하지만 읽을 수있는 함수도 있습니다.
/** * Flattens a multi demensional array into a one dimensional * to be compatible with hidden html fields. * * @param array $array * Array in the form: * array( * 'a' => array( * 'b' => '1' * ) * ) * * @return array * Array in the form: * array( * 'a[b]' => 1, * ) */ function flatten_array($array) { // Continue until $array is a one-dimensional array. $continue = TRUE; while ($continue) { $continue = FALSE; // Walk through top and second level of $array and move // all values in the second level up one level. foreach ($array as $key => $value) { if (is_array($value)) { // Second level found, therefore continue. $continue = TRUE; // Move each value a level up. foreach ($value as $child_key => $child_value) { $array[$key . '[' . $child_key . ']'] = $child_value; } // Remove second level array from top level. unset($array[$key]); } } } return $array; }
-
==============================
20.
아, 재귀없이! 심지어지도, 감소, 필터 재귀가 포함됩니다. 그것과 같은 몇 가지 해키 PHP는 방법을 사용하지 않는 한 불가능합니다. 진지하게, 아래의 코드에 관련된 루프가 없습니다, 좋은 배열 함수를 살해 한 사람은 죄송합니다 :)
$arr=array(1,2,array(3,4, array(5,6,7), 8), 9); $json=json_encode($arr); $hacked_json=str_replace(['[',']'],"",$json); $hacked_array=json_decode('['.$hacked_json.']'); echo "<pre>"; print_r($hacked_array);
산출
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 1 [5] => 2 [6] => 6 [7] => 7 [8] => 8 [9] => 9 )
중첩 된 키 값 쌍에 대해서도 작동합니다.
$arr=array(1,2,array(3,4, array(array("s"=>array(1),"w"=>array('q'=>1,'v'=>12)),6,7), 8), 9); echo "<pre>"; print_r($arr); $json=json_encode($arr); $hacked_json=str_replace(['[',']'],"",$json); $hacked_array=json_decode('['.$hacked_json.']'); echo "<pre>"; print_r(json_decode(json_encode($hacked_array), True));
산출
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => Array ( [s] => 1 [w] => Array ( [q] => 1 [v] => 12 ) ) [5] => 6 [6] => 7 [7] => 8 [8] => 9 )
-
==============================
21.
이것은 참조를 사용하여 내 솔루션입니다 :
function arrayFlatten($array_in, &$array_out){ if(is_array($array_in)){ foreach ($array_in as $element){ arrayFlatten($element, $array_out); } } else{ $array_out[] = $array_in; } } $arr1 = array('1', '2', array(array(array('3'), '4', '5')), array(array('6'))); arrayFlatten($arr1, $arr2); echo "<pre>"; print_r($arr2); echo "</pre>";
-
==============================
22.
<?php //recursive solution //test array $nested_array = [[1,2,[3]],4,[5],[[[6,[7=>[7,8,9,10]]]]]]; /*----------------------------------------- function call and return result to an array ------------------------------------------*/ $index_count = 1; $flatered_array = array(); $flatered_array = flat_array($nested_array, $index_count); /*----------------------------------------- Print Result -----------------------------------------*/ echo "<pre>"; print_r($flatered_array); /*----------------------------------------- function to flaten an array -----------------------------------------*/ function flat_array($nested_array, & $index_count, & $flatered_array) { foreach($nested_array AS $key=>$val) { if(is_array($val)) { flat_array($val, $index_count, $flatered_array); } else { $flatered_array[$index_count] = $val; ++$index_count; } } return $flatered_array; } ?>
-
==============================
23.
다음은 간단한 접근법입니다.
$My_Array = array(1,2,array(3,4, array(5,6,7), 8), 9); function checkArray($value) { foreach ($value as $var) { if ( is_array($var) ) { checkArray($var); } else { echo $var; } } } checkArray($My_Array);
-
==============================
24.
HTML 다차원 배열을 HTML 입력 형식으로 표현해야했습니다.
$test = [ 'a' => [ 'b' => [ 'c' => ['a', 'b'] ] ], 'b' => 'c', 'c' => [ 'd' => 'e' ] ]; $flatten = function ($input, $parent = []) use (&$flatten) { $return = []; foreach ($input as $k => $v) { if (is_array($v)) { $return = array_merge($return, $flatten($v, array_merge($parent, [$k]))); } else { if ($parent) { $key = implode('][', $parent) . '][' . $k . ']'; if (substr_count($key, ']') != substr_count($key, '[')) { $key = preg_replace('/\]/', '', $key, 1); } } else { $key = $k; } $return[$key] = $v; } } return $return; }; die(var_dump( $flatten($test) )); array(4) { ["a[b][c][0]"]=> string(1) "a" ["a[b][c][1]"]=> string(1) "b" ["b"]=> string(1) "c" ["c[d]"]=> string(1) "e" }
-
==============================
25.
객체의 배열을 가지고 노드를 사용하여 객체를 병합하려면 다음 함수를 사용하십시오.
function objectArray_flatten($array,$childField) { $result = array(); foreach ($array as $node) { $result[] = $node; if(isset($node->$childField)) { $result = array_merge( $result, objectArray_flatten($node->$childField,$childField) ); unset($node->$childField); } } return $result; }
-
==============================
26.
PHP 7부터, 내가 아는 것은 아닙니다. 나는 다차원 배열을 평평하게하고 중복 제거하기 위해 참조와 재귀 모두를 사용하고 다차원 배열 재구성을 위해 발견 된 각 복제물에 대해 가장 깊은 노드의 깊이를 보존하는 array_moonwalk를 호출하는 솔루션을 만들었습니다.
foreach를 사용하지 않고 다른 깊이의 리프 노드 중복 제거를 처리하며 array_walk를 활용하는 유일한 해결책입니다. 성능을 테스트하지 않았습니다. YMMV.
from https://stackoverflow.com/questions/1319903/how-to-flatten-a-multidimensional-array by cc-by-sa and MIT lisence
'PHP' 카테고리의 다른 글
A 요소의 href 속성 가져 오기 (0) | 2018.09.02 |
---|---|
참조 - PDO에 대해 자주 묻는 질문 (0) | 2018.09.02 |
PHP에서 다차원 배열에서 중복 값을 제거하는 방법 (0) | 2018.09.02 |
PHP에서 HTML / XML을 구문 분석하고 처리하는 방법은 무엇입니까? (0) | 2018.09.02 |
PHP에서 유용한 오류 메시지를 얻는 방법? (0) | 2018.09.02 |