多次元配列をフラット化する方法は?


259

PHPで、再帰や参照を使用せずに(二/多)次元配列をフラット化することは可能ですか?

私は値にのみ興味があるので、キーは無視できます。array_map()との行で考えていarray_values()ます。


17
なぜ再帰を避けますか?
JorenB 2009

5
だまされやすい人(主に)stackoverflow.com/questions/526556/...
cletus

4
再帰なしでは、任意の深さの配列のすべての要素で何もできません(反復として偽装できますが、potato、potahto)。再帰処理コードを自分で記述したくない場合は、dk2.php.net /を使用します使用可能な配列に要素を追加するコールバックを備えたmanual / en / function.array-walk-recursive.php(グローバル、userdataパラメーターを使用し、すべてをクラスに入れて$ thisを参照するなど)
Michael Madsen

@JorenB:実装がアーカイブされることを望んでいます。
Alix Axel

Nsplのflatten関数を見てください。深さも指定できます。
Ihor Burlachenko 2016

回答:


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 09

45
それは「キャッチー」よりも「論理的」です。すべてがJOGL、Knol、Azureのような素晴らしい名前を持つことができるわけではありません:-)
VolkerK

7
これは、子としての空の配列に対しては機能しません。親として返却されます。
11

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); }これが他の人を助けることを願っています。
マイク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($ array、function($ a、$ b)use(&$ return){$ return [$ b] = $ a;}); $ returnを返します。}
Brendon-Van-Heyzen

これをphp 5.2で使用するように書き直すことができますか?
Alex

2
@Alex残念ながら、これは参照によるオプションのパラメーターを受け入れないため、useこれを使用するための構文が必要array_walk_recursiveです$userdata
Tim Seguine

1
そのようなアレイではうまく機能するように見えますが-> ideone.com/DsmApPしかし、そのようなアレイではうまくいきません-> ideone.com/5Kltva またはそれは私ですか?
Sebastian Piskorski 2014

2
@Sebastian Piskorskiこれは、値がキーのように扱われるためです。つまり、配列に独自のkey => valueペアを導入するとすぐに、最初のインデックス位置の配列値は、値のないキーのように扱われます。一意になるように、2つのキーが一致する場合、値は同じキーに追加されます。簡単な解決策は、配列を最初にソートすることです。これは、PHPに固有の動作です。
Martyn Shut、2015

92

2次元配列のソリューション

これを試してください:

$array  = your array

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

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

編集:2013年8月21日

多次元配列で機能するソリューションは次のとおりです。

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


ありがとう、最初の1つはPDOから取得したアレイで動作しましたが、他のソリューションでは動作しませんでした。
JAL

7
これは貧弱な戦略です。call_user_func_array('array_merge', [])(空の配列に注意)nullを返し、php警告エラーをトリガーします。配列が空にならないという事実を知っている場合、これは洗練されたソリューションですが、それは多くの人が行うことができる一般的な仮定ではありません。
ヤギ

OPは非再帰的なソリューションを具体的に求めました。
エレクトラ

わあ、クールな2Dフラッタン!しかし、通知を防ぐために使用するだけ$result = $array ?call_user_func_array('array_merge', $array) : [];
Alexander Goncharov

かっこいいですが、偶然に逆関数の配列がデフラットしていませんか?
FantomX1 2018

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引数なしで呼び出されるされます。最初の引数として空の配列を追加することで回避できます。

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

1
これは、配列のすべての要素が配列である場合にのみ機能します。配列がスカラーなどの混合型で構成される場合、エラーが発生します。
Otheus

@Otheusこれは、上記のソリューションが再帰を使用しないためです。あなたが言ったように、それは配列の配列を必要とします。しかしプラス面では、関数呼び出しの追加のオーバーヘッドがないため、他のメソッドよりもはるかに高速です。
Joyce Babu

2
外側の配列が空の場合はエラーをスローします。空の配列と組み合わせると回避できますarray_merge([], ...$a);
Mohamed Gharib

@MohamedGharibいいキャッチ。
Joyce Babu

連想配列を使用している場合、あなたは、このソリューションをチェックすることができstackoverflow.com/questions/40663687/...
アレックス・

24

(要求したとおりに)再帰なしでフラット化するには、スタックを使用できます。当然、これをのような独自の関数に入れることができます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は再帰を使用するため、実際に何が必要かによって異なります。スタックに基づいて再帰的なイテレータを作成することも可能でなければなりません:

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

デモ

これまでのところ、RecursiveIterator私は良いアイデアだと思うスタックを実装することはしませんでした。


未処理のarray_flatten関数の場合は+1。私は追加する必要がありましたif(!empty($value)){$flat[] = $value}結果の配列に追加空の状態を防ぐために、else文の内側。素晴らしい機能!
Alex Sarnowski 2017年

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の答えを引用する:

ただ、2番目のパラメータとして偽を追加($use_keys)するiterator_to_arrayコール


明確にするために、これはキー(数値のキーも含む)を保持するため、同じキーを持つ値は失われます。たとえばに$array = ['a',['b','c']]なりArray ([0] => b, [1] => c )ます。ものキーを持っている'a'ため'b'、失われます0
Nigel Alderton 2017年

1
@NigelAlderton 呼び出しにfalse2番目のパラメーター($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)(「(...)再帰の恐怖は、(消費します... ) ")、2013年2月5日に作成されましたか?
trejder 2013年

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多次元です!= 2次元ですが、これは任意の数のレベルを平坦化するように構成できます。折りたたみを構成することの1つの素晴らしい結果は、固定された制限に従うことです。5レベルにネストされた配列がある場合、fold4レベルにしたりfold . fold、3レベルにしたりfold . fold . fold、2レベルにしたりすることができます。これにより、バグが非表示になるのを防ぐこともできます。例えば。5D配列をフラット化したいが、4D配列が与えられた場合、エラーはすぐにトリガーされます。
ウォーボ2013

2次元配列の場合、このソリューションが大好きです。手形にぴったりフィットします。
Tom Auger 2016年

あなたの単一レベルの定義が最良の答えであることにも同意します。しかし$concat、あなたは間違った名前を付けたと思いますが、単にそれを呼ぶべきだと思います$flattenarray_mergePHPのconcatに相当します。私が試した取得する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自体を追加します。このコードを実行すると、無限にループします。
トッドオーウェン

はい、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で動作する場合は2番目に、すべてのデータで動作しない場合は3番目にそれを知っておく必要があります。
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」の答えだと思います。
アーシャム2013


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 '19

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


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

PHPの多次元配列を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"
}


@AlixAxelこのコメントは相対的ですか?間違った投稿..?
Gajus 2013

いいえ。私はあなたがしていることとかなり似ていると思い、それを共有することにしました。唯一の違いは、私の表現が有効なPHPでもあるということ$var['a']['b']['c'][0] = 'a'; ...です。
Alix Axel

意図的にHTML出力が必要でした。共有していただきありがとうございます。
Gajus 2013

1
これは間違った質問に対する正しい答えだと思います。回答するときは、質問されたとおりに回答してください。そうしないと、ページがコア問題から逸脱し、将来の研究者が混乱する可能性があります。
mickmackusa '19

-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.