27

ドット表記を使用して PHP 配列にアクセスするためのヒントやコード例はたくさんありますが、私は逆のことをしたいと思います。次のような多次元配列を取得したいと思います。

$myArray = array(
    'key1' => 'value1',
    'key2' => array(
        'subkey' => 'subkeyval'
    ),
    'key3' => 'value3',
    'key4' => array(
        'subkey4' => array(
            'subsubkey4' => 'subsubkeyval4',
            'subsubkey5' => 'subsubkeyval5',
        ),
        'subkey5' => 'subkeyval5'
    )
);

そして、これを次のようにします (再帰関数を使用する可能性があります)。

$newArray = array(
    'key1'                    => 'value1',
    'key2.subkey'             => 'subkeyval',
    'key3'                    => 'value3',
    'key4.subkey4.subsubkey4' => 'subsubkeyval4',
    'key4.subkey5.subsubkey5' => 'subsubkeyval5',
    'key4.subkey5'            => 'subkeyval5'
);
4

5 に答える 5

79

コードズ

$ritit = new RecursiveIteratorIterator(new RecursiveArrayIterator($myArray));
$result = array();
foreach ($ritit as $leafValue) {
    $keys = array();
    foreach (range(0, $ritit->getDepth()) as $depth) {
        $keys[] = $ritit->getSubIterator($depth)->key();
    }
    $result[ join('.', $keys) ] = $leafValue;
}

出力

Array
(
    [key1] => value1
    [key2.subkey] => subkeyval
    [key3] => value3
    [key4.subkey4.subsubkey4] => subsubkeyval4
    [key4.subkey4.subsubkey5] => subsubkeyval5
    [key4.subkey5] => subkeyval5
)

デモ: http://codepad.org/YiygqxTM

私は行く必要がありますが、明日その説明が必要な場合は、私に聞いてください.

于 2012-05-03T02:57:25.547 に答える
5

これにより、任意のレベルのネストが処理されます。

<? //PHP 5.4+
$dotFlatten = static function(array $item, $context = '') use (&$dotFlatten){
    $retval = [];
    foreach($item as $key => $value){
        if (\is_array($value) === true){
            foreach($dotFlatten($value, "$context$key.") as $iKey => $iValue){
                $retval[$iKey] = $iValue;
            }
        } else {
            $retval["$context$key"] = $value;
        }
    }
    return $retval;
};

var_dump(
    $dotFlatten(
        [
            'key1' => 'value1',
            'key2' => [
                'subkey' => 'subkeyval',
            ],
            'key3' => 'value3',
            'key4' => [
                'subkey4' => [
                    'subsubkey4' => 'subsubkeyval4',
                    'subsubkey5' => 'subsubkeyval5',
                ],
                'subkey5' => 'subkeyval5',
            ],
        ]
    )
);
?>
于 2012-05-03T03:11:05.617 に答える
4

との答えはすでにありますRecursiveIteratorIterator。しかし、ネストされたループの使用を回避する、より最適なソリューションを次に示します。

$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($arr),
    RecursiveIteratorIterator::SELF_FIRST
);
$path = [];
$flatArray = [];

foreach ($iterator as $key => $value) {
    $path[$iterator->getDepth()] = $key;

    if (!is_array($value)) {
        $flatArray[
            implode('.', array_slice($path, 0, $iterator->getDepth() + 1))
        ] = $value;
    }
}

ここでいくつかの点を確認する必要があります。RecursiveIteratorIterator::SELF_FIRSTここでの定数の使用に注意してください。RecursiveIteratorIterator::LEAVES_ONLYデフォルトではすべてのキーにアクセスできないため、これは重要です。したがって、この定数セットを使用して、配列の最上位レベルから開始し、さらに深くなります。RecursiveIteratorIterator::getDepthこのアプローチにより、キーの履歴を保存し、メソッドを使用してリーフをリッチにするときにキーを準備できます。

これが動作するデモです。

于 2016-10-24T11:37:51.320 に答える
2

これは、任意の深さの配列で機能する再帰的なソリューションに対する私の見解です。

function convertArray($arr, $narr = array(), $nkey = '') {
    foreach ($arr as $key => $value) {
        if (is_array($value)) {
            $narr = array_merge($narr, convertArray($value, $narr, $nkey . $key . '.'));
        } else {
            $narr[$nkey . $key] = $value;
        }
    }

    return $narr;
}

として呼び出すことができます$newArray = convertArray($myArray)

于 2012-05-03T03:19:46.697 に答える