[php] 다차원 배열을 평평하게하는 방법?

PHP에서 재귀 또는 참조를 사용하지 않고 (bi / multi) 차원 배열을 평평하게 할 수 있습니까?

값에만 관심이 있으므로 키를 무시할 수 있습니다 . array_map()및 의 줄을 생각 하고 array_values()있습니다.



답변

당신이 사용할 수있는 표준 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 


답변

현재 PHP 5.3 , 최단 솔루션이 될 것으로 보인다 array_walk_recursive()새로운 클로저 구문 :

function flatten(array $array) {
    $return = array();
    array_walk_recursive($array, function($a) use (&$return) { $return[] = $a; });
    return $return;
}


답변

2 차원 배열 솔루션

이것을 시도하십시오 :

$array  = your array

$result = call_user_func_array('array_merge', $array);

echo "<pre>";
print_r($result);

편집 : 21-Aug-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


답변

PHP 5.6 이상에서는 연산자로 array_merge외부 배열의 압축을 푼 후 2 차원 배열을 평탄화 할 수 있습니다 .... 코드는 간단하고 명확합니다.

array_merge(...$a);

이것은 연관 배열 컬렉션에서도 작동합니다.

$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
)

업데이트 : @MohamedGharib의 코멘트에 근거

외부 배열이 비어 있으면 array_merge인수가 0으로 호출 되므로 오류가 발생합니다 . 빈 배열을 첫 번째 인수로 추가하면 피할 수 있습니다.

array_merge([], ...$a);


답변

요청없이 재귀없이 평평하게하기 위해 stack을 사용할 수 있습니다 . 당연히 이것을 자신의 기능에 넣을 수 있습니다 array_flatten. 다음은 키없이 작동하는 버전입니다.

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 키를 유지하면서 다차원 배열을 통해 걷기

확실하지는 않지만 II는 과거에 이것을 테스트했습니다 RecurisiveIterator.The recursion을 사용하므로 실제로 필요한 것에 달려 있습니다. 스택을 기반으로 재귀 반복자를 만들 수 있어야합니다.

foreach(new FlatRecursiveArrayIterator($array) as $key => $value)
{
    echo "** ($key) $value\n";
}

데모

나는 그것이 RecursiveIterator좋은 생각이라고 생각 하는 스택을 구현하기 위해 지금까지하지 않았다 .


답변

간단 하고 한 줄 답변.

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 의 우려 / 문제 인용 :

명확히하기 위해 키 (숫자조차도)를 유지하므로 동일한 키를 가진 값이 손실됩니다. 예를 들어 $array = ['a',['b','c']]이된다 Array ([0] => b, [1] => c ). 의 키가 'a'있기 때문에'b'0

인용 Svish 의 답변 :

iterator_to_array 호출에 두 번째 매개 변수 ($use_keys)로 false를 추가 하십시오.


답변

재귀를 사용합니다. 그것이 복잡하지 않은 것을 보았을 때, 재복에 대한 두려움은 그것이 복잡하지 않은 것을 보았을 때 사라질 것입니다.

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>