28

重複の可能性:
PHP は、キーの連結中にネストされた配列を単一の配列に変換しますか?
配列のキーを再帰的に取得し、アンダースコアで区切られた文字列を作成します

回答する前に、質問全体をお読みください。

私はこの多次元配列を持っています:

$data = array(
    'user' => array(
        'email'   => 'user@example.com',
        'name'    => 'Super User',
        'address' => array(
            'billing' => 'Street 1',
            'delivery' => 'Street 2'
        )
    ),
    'post' => 'Hello, World!'
);

平らにして、次のように変換します。

$data = array(
    'user.email' => 'user@example.com',
    'user.name'  => 'Super User',
    'user.address.billing'  => 'Street 1',
    'user.address.delivery' => 'Street 2',
    'post'       => 'Hello, World!'
);

重要:

  • キーは私にとって非常に重要です。ピリオドで区切って連結したい。

  • どのレベルのネストでも機能するはずです。

ありがとうございました!

4

5 に答える 5

72

このようなものが動作するはずです:

function flatten($array, $prefix = '') {
    $result = array();
    foreach($array as $key=>$value) {
        if(is_array($value)) {
            $result = $result + flatten($value, $prefix . $key . '.');
        }
        else {
            $result[$prefix . $key] = $value;
        }
    }
    return $result;
}

デモ

于 2012-03-03T12:39:51.650 に答える
21

与えられたすべての答えに感謝します。

私はそれを次のように変換しました。これは改良版です。ルートプレフィックスが不要になり、参照を使用する必要がなくなり、読みやすくなり、より良い名前が付けられます。

function array_flat($array, $prefix = '')
{
    $result = array();

    foreach ($array as $key => $value)
    {
        $new_key = $prefix . (empty($prefix) ? '' : '.') . $key;

        if (is_array($value))
        {
            $result = array_merge($result, array_flat($value, $new_key));
        }
        else
        {
            $result[$new_key] = $value;
        }
    }

    return $result;
}
于 2012-03-03T12:55:37.657 に答える
9

これを試して

<?php

$data = array(
    'user' => array(
        'email'   => 'user@example.com',
        'name'    => 'Super User',
        'address' => array(
            'billing' => 'Street 1',
            'delivery' => 'Street 2'
        )
    ),
    'post' => 'Hello, World!'
);

function prefixKey($prefix, $array)
{
    $result = array();
    foreach ($array as $key => $value)
    {
        if (is_array($value))
            $result = array_merge($result, prefixKey($prefix . $key . '.', $value));
        else
            $result[$prefix . $key] = $value;
    }   
    return $result;
}

var_dump(prefixKey('', $data));

?>

出力

array
  'user.email' => string 'user@example.com' (length=16)
  'user.name' => string 'Super User' (length=10)
  'user.address.billing' => string 'Street 1' (length=8)
  'user.address.delivery' => string 'Street 2' (length=8)
  'post' => string 'Hello, World!' (length=13)
于 2012-03-03T12:43:17.887 に答える
2

ここでこれをテストします

参照渡しなので返品は不要です。アレイストレージを引き渡すだけです。

$store = array();

function flatten($array,&$storage,$parentKey = ''){
    foreach($array as $key => $value){
    $itemKey = (($parentKey)? $parentKey.'.':'').$key;
        if(is_array($value)){
            flatten($value,$storage,$itemKey);
        } else {
            $storage[$itemKey] = $value;
        }
    }   
}

flatten($data,$store);
var_dump($store);
于 2012-03-03T12:54:45.143 に答える
1

次のような再帰を使用します。

function process_data( $data, $parent_key ){

    if ( ! is_array( $data ) ){
        return $data;
    }

    $flattened_array = array();
    foreach( $data as $key => $item ){
        $flattened_key = $parent_key . '.' . $key;
        $flattened_array[ $flattened_key ] = process_data( $item, $flattened_key );
    }

    return $flattened_array;

}
于 2012-03-03T12:44:20.907 に答える