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


259

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

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


17
재귀를 피해야하는 이유는 무엇입니까?
JorenB


4
재귀없이 임의로 깊은 배열의 모든 요소를 ​​사용하여 아무것도 할 수 없습니다 (반복으로 위장 할 수는 있지만 감자, potahto). 재귀 처리 코드를 직접 작성하지 않으려면 dk2.php.net/을 사용 하십시오. 사용 가능한 배열에 요소를 추가하는 콜백이 포함 된 manual / en / function.array-walk-recursive.php (전역, userdata 매개 변수 사용, 모든 클래스에 넣고 $ this 등 참조)
Michael Madsen

@JorenB : 구현이 보관 될 수 있기를 바랍니다.
Alix Axel

Nspl 에서 flatten 함수를 살펴보십시오 . 깊이를 지정할 수도 있습니다.
Ihor Burlachenko

답변:


276

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

351
'RecursiveIteratorIterator'가 바보 같은 이름이라고 생각하는 유일한 사람입니까?
nilamo

45
"catchy"보다 "논리적"입니다. 모든 것이 JOGL, 놀 (Knol) 또는 푸른 :-) 같은 환상적인 이름을 가질 수 있습니다
VolkerK

7
빈 배열에는 자식으로 작동하지 않습니다. 그들은 부모로 반환됩니다.
hakre

45
iterator_to_array($it, false)foreach의 필요성을 피하십시오.
Alix Axel

3
다른 사람들이 발표 한 내용을 바탕으로이 작은 도우미를 만들 수있었습니다 function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }. 다른 사람들에게 도움이되기를 바랍니다.
Mike S.

295

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

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

33
키를 원한다면, flatten (array $ array) {$ return = array (); array_walk_recursive ($ 배열, 함수 ($ a, $ b) 사용 (& $ return) {$ return [$ b] = $ a;}); 반환 $ 반환; }
Brendon-Van-Heyzen

PHP 5.2에서 사용하도록 다시 작성할 수 있습니까?
Alex

2
@Alex 불행히도이 매개 변수를 참조 하려면 선택적 매개 변수를 허용하지 usearray_walk_recursive$userdata
않으므로이

1
그런 배열에는 잘 작동하는 것 같습니다-> ideone.com/DsmApP 그러나 그런 배열 에는 적합하지 않습니다-> ideone.com/5Kltva 아니면 나입니까?
Sebastian Piskorski

2
@Sebastian Piskorski는 값이 키처럼 취급되기 때문에 배열에 자신의 키 => 값 쌍을 도입하자마자 첫 번째 인덱스 위치의 배열 값은 값이없는 키처럼 취급되며 키는 두 개의 키가 일치하는 경우 고유 한 값을 갖기 위해 값이 동일한 키에 추가됩니다. 간단한 해결책은 배열을 먼저 정렬하는 것입니다. 이것은 PHP 고유의 동작입니다.
Martyn Shutt

92

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


감사합니다. 첫 번째 솔루션은 다른 솔루션으로는 그렇지 않은 PDO에서 얻은 어레이에서 작동했습니다.
JAL

7
이것은 나쁜 전략입니다. call_user_func_array('array_merge', [])(빈 배열에 주목) null을 반환하고 PHP 경고 오류를 트리거합니다. 배열이 비어 있지 않다는 사실을 알고 있으면 매끄러운 솔루션이지만 많은 사람들이 할 수있는 일반적인 가정은 아닙니다.
염소

OP는 비 재귀 솔루션을 구체적으로 요청했습니다.
Élektra

와, 2D flattern을 시원하게! 그러나 공지를 막기 위해$result = $array ?call_user_func_array('array_merge', $array) : [];
Alexander Goncharov

멋진 bruh, 그러나 우연히 카운터 함수 배열이 수축되지 않습니까?
FantomX1

64

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

1
이것은 배열의 모든 요소가 배열 인 경우에만 작동합니다. 배열이 스칼라와 같은 혼합 유형을 포함하는 경우 오류가 발생합니다.
테우스

@Otheus 위의 솔루션은 재귀를 사용하지 않기 때문입니다. 말했듯이 배열 배열이 필요합니다. 그러나 장점은 함수 호출의 추가 오버 헤드가 없기 때문에 다른 방법보다 훨씬 빠릅니다.
Joyce Babu

2
외부 배열이 비어 있으면 오류가 발생합니다. 빈 배열과 결합하면 피할 수 있습니다array_merge([], ...$a);
Mohamed Gharib

@MohamedGharib 좋은 캐치.
Joyce Babu

연관 배열을 사용하는 경우이 솔루션을 확인할 수 있습니다. stackoverflow.com/questions/40663687/…
alex

24

요청없이 재귀없이 평평하게하기 위해 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좋은 생각이라고 생각 하는 스택을 구현하기 위해 지금까지하지 않았다 .


뛰어난 array_flatten 함수의 경우 +1 내가 추가 한 if(!empty($value)){$flat[] = $value}결과 배열에 추가 빈 존재를 방지하기 위해 다른 문 내부. 멋진 기능!
Alex Sarnowski

19

간단 하고 한 줄 답변.

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를 추가 하십시오.


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

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

18

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

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>

1
나는 재귀를 두려워하지 않고 다른 방법으로 배우고 싶습니다.
Alix Axel

13
이 재귀에 대해 +1 : 복잡하지 않은 것을보고 재귀에 대한 두려움이 사라지는 것을 잊어 버리기를 바랍니다.
Tiberiu-Ionuț Stan 2013

1
알았어, 나 끝났어 방법 은, 그 회신 ( "나는 재귀를 두려워하지 않는다") 가능하며 3 년 반 년 이전 (초기 문 이상 (8월 24일 '09) ( "(...) 재귀의 두려움은 사라집니다 ... ) "), 13 년 2 월 5 일에 작성 되었습니까?
trejder 2016 년

18

방금 이것이 폴드이므로 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 ​​행을 따라 결합기 함수를 요청합니다.


다차원! = 이차원.
Alix Axel

@atamur PHP 5.3 이상에서 작동합니다. array_reduce에 대한 변경 로그에서 언급했듯이 $ initial은 5.3 이전의 정수일 수 있으며 "혼합"될 수 있습니다 (즉, 축소 함수가 지원하는 모든 것)
Warbo

1
@AlixAxel 당신은 다차원! = 이차원이라고 맞습니다. 그러나 이것은 여러 레벨을 평평하게 구성 할 수 있습니다. 접기를 구성하면 좋은 결과는 고정 된 제한을 따릅니다. 배열이 5 레벨로 중첩 된 경우 fold4 레벨로 배열 하거나 fold . fold3 레벨 fold . fold . fold을 얻 거나 2 레벨을 얻을 수 있습니다. 이렇게하면 버그가 숨겨지지 않습니다. 예. 5D 배열을 평면화하고 싶지만 4D 배열이 제공되면 오류가 즉시 트리거됩니다.
Warbo

2 차원 배열 에이 솔루션을 좋아합니다. 청구서를 완벽하게 맞습니다.
Tom Auger

나는 당신의 단일 수준의 정의가 가장 좋은 대답이라는 것에 동의합니다. 그러나 나는 당신이 그것을 잘못 명명 $concat했다고 생각합니다 $flatten. array_mergeconcat에 해당하는 PHP입니다. 나는 시도 얻을 array_concat에 대한 별칭으로 추가 array_merge.
icc97

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]

5

이 솔루션은 비재 귀적입니다. 요소의 순서는 다소 혼합되어 있습니다.

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;
}

1
영리한 생각이지만 버그가 있습니다. "$ array [] = $ value"는 $ value의 모든 요소 를 $ array에 추가하지 않고 단지 $ value 자체를 추가합니다. 이 코드를 실행하면 무한정 반복됩니다.
Todd Owen

예, shifting배열에서 벗어난 값을 다시 끝에 추가하는 것은별로 의미가 없습니다. 당신이 array_merge()대신하고 싶었던 것 같아요 ?
deceze

4

나는 이것이 돌연변이 나 익숙하지 않은 클래스를 사용하지 않는 가장 깨끗한 해결책이라고 생각합니다.

<?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));

3

다음과 같은 간단한 기능을 시도하십시오.

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',
)

아마도 당신은 당신의 기능을 확인해야합니다 ... 예상대로 작동하지 않는 것 같습니다
Emiliano

@Emiliano 새로운 질문을 해보십시오. 입력 데이터가 다를 수 있으므로 특정 경우에는 작동하지 않습니다.
kenorb

우리는 각각 더 이상 사용되지 않는 함수라는 문제가 거의 없습니다. 여기서 새로운 사람이 아니었다는 점을 개선 할 수 있습니다. 코드가 특정 버전의 PHP로 작동하면 두 번째로 알아야합니다. 모든 데이터로 작동하지 않으면 세 번째로 말하십시오.
Emiliano

2

트릭은 소스 및 대상 배열을 모두 참조로 전달하는 것입니다.

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

2
/**
 * 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));
    }
);

요지 스 니펫


이것은 2 차원 배열 만 지원하는 것 같습니다.
Alix Axel

네 말이 맞아 그것을 사용할 필요가 없습니다. 가장 좋은 해결책은 "너무 많은 PHP"의 대답이라고 생각합니다.
Arsham


2

재귀를 정말로 좋아하지 않는다면 ... 대신 이동하십시오 :)

$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];
    }
}

참고 : 이 간단한 버전에서는 배열 키를 지원하지 않습니다.


이것은 흥미로운 접근법입니다. 다른 솔루션과 달리 원래 배열 ($ a)을 편집합니다. 를 continue로 바꾸면 다소 빠릅니다.
pcarvalho

2

재귀 생성기를 사용하는 것은 어떻습니까? https://ideone.com/d0TXCg

<?php

$array = [
    'name' => 'Allen Linatoc',
    'profile' => [
        'age' => 21,
        'favourite_games' => [ 'Call of Duty', 'Titanfall', 'Far Cry' ]
    ]
];

foreach (iterate($array) as $item) {
    var_dump($item);
};

function iterate($array)
{
    foreach ($array as $item) {
        if (is_array($item)) {
            yield from iterate($item);
        } else {
            yield $item;
        }
    }
}

1

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;
}

이 코드 전용 답변에 설명을 포함하십시오.
mickmackusa

1

이 버전은 깊거나 얕거나 특정 수준의 레벨을 수행 할 수 있습니다.

/**
 * @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;
}

이 스 니펫 수행 할 수있는 작업을 설명하는 것 외에도 향후 연구원에게 작동 방식을 설명하십시오.
mickmackusa

1

여기 코드 가 무섭게 보이기 때문입니다. 다음은 다차원 배열을 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;
}

1

이것은을 사용하여 달성 할 수 있습니다 array_walk_recursive

$a = array(1,2,array(3,4, array(5,6,7), 8), 9);
array_walk_recursive($a, function($v) use (&$r){$r[]=$v;});
print_r($r);

작업 예 :-https: //3v4l.org/FpIrG


0

이것은 참조를 사용하여 내 솔루션입니다.

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>";

스 니펫의 작동 방식과 왜 좋은 아이디어인지 설명해주세요. 코드 전용 답변은 OP 및 미래 연구원을 교육 / 강화하는 데 나쁜 역할을하기 때문에 StackOverflow에서 가치가 낮습니다. 우리는 결코 OP에게만 말하고 있지 않습니다. 이전 페이지는 새 페이지를 닫는 데 사용되므로 향후 요청자에게도 문제를 해결하기에 충분한 정보를 제공해야합니다.
mickmackusa

0
<?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;
}
?>

0

간단한 접근 방식은 다음과 같습니다.

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

0

이것에 대한 정말 깨끗한 해결책을 찾는 사람은 누구나 있습니다. 옵션은 다음과 같습니다.

$test_array = array(
    array('test' => 0, 0, 0, 0),
    array(0, 0, 'merp' => array('herp' => 'derp'), 0),
    array(0, 0, 0, 0),
    array(0, 0, 0, 0)
);
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($test_array));
var_dump( iterator_to_array($it, false) ) ; 

인쇄물

 0 0 0 0 0 0 derp 0 0 0 0 0 0 0 0 0

0

다른 솔루션을 게시하면됩니다)

function flatMultidimensionalArray(array &$_arr): array
{
    $result = [];
    \array_walk_recursive($_arr, static function (&$value, &$key) use (&$result) {
        $result[$key] = $value;
    });

    return $result;
}

0

솔루션 인 키도 유지하려는 경우.

function reduce(array $array) {
    $return = array();
    array_walk_recursive($array, function($value, $key) use (&$return) { $return[$key] = $value; });
    return $return;
}

불행히도 중간 키없이 최종 중첩 배열 만 출력합니다. 다음 예제의 경우 :

$array = array(
    'sweet' => array(
        'a' => 'apple',
        'b' => 'banana'),
    'sour' => 'lemon'); 
print_r(flatten($fruits));

출력은 다음과 같습니다

Array
(
    [a] => apple
    [b] => banana
    [sour] => lemon
)

-1

HTML 입력 형식으로 PHP 다차원 배열을 표현해야했습니다.

$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"
}


@AlixAxel이 의견은 어떻게 상대적인가? 잘못된 게시물 ..?
Gajus

아닙니다. 나는 그것이 당신이하고있는 것과 매우 비슷하다고 생각하고 그것을 공유하기로 결정했습니다. 유일한 차이점은 내 표현이 유효한 PHP 형식이라는 것 $var['a']['b']['c'][0] = 'a'; ...입니다.
Alix Axel

의도적으로 HTML 출력이 필요했습니다. 공유해 주셔서 감사합니다.
Gajus

1
나는 이것이 잘못된 질문에 대한 정답이라고 생각합니다. 답변 할 때는 질문에 따라 답변을 시도하십시오. 그렇지 않으면 페이지가 핵심 문제에서 벗어나 미래의 연구원들을 혼란스럽게 할 수 있습니다.
mickmackusa

-1

객체 배열이 있고 노드로 평면화하려는 경우이 함수를 사용하십시오.

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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.