Сгладить многомерный массив, объединяющий ключи

Возможный дубликат:
PHP преобразовать вложенный массив в один массив при объединении ключей?
Рекурсивно получить ключ массива и создать разделенную строку подчеркивания

Пожалуйста, прочитайте весь вопрос, прежде чем отвечать.

У меня есть этот многомерный массив:

$data = array(
    'user' => array(
        'email'   => '[email protected]',
        'name'    => 'Super User',
        'address' => array(
            'billing' => 'Street 1',
            'delivery' => 'Street 2'
        )
    ),
    'post' => 'Hello, World!'
);

Я хочу, чтобы он сгладился, превратился в:

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

Важно:

  • Ключи очень важны для меня. Я хочу, чтобы они были объединены, разделены точками.

  • Он должен работать с любым уровнем вложенности.

Спасибо!


person J. Bruni    schedule 03.03.2012    source источник
comment
Есть несколько похожих вопросов, но я не нашел дубликата.   -  person J. Bruni    schedule 03.03.2012
comment
Действительно, есть два дубликата. Я не знал, когда спрашивал. В любом случае, все ответы на них (кроме ответа Мигара) намного хуже, чем те, которые приведены здесь сейчас... они излишне сложны (используя итераторы, глобальные переменные, классы и т.п., когда это может быть так же просто, как мы можем видеть здесь ).   -  person J. Bruni    schedule 03.03.2012


Ответы (5)


Что-то вроде этого должно работать:

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

ДЕМО

person Felix Kling    schedule 03.03.2012
comment
Спасибо! у вас также есть аналог? создать мультимассив из этого плоского массива? - person user706420; 26.06.2016
comment
сэр, спасибо, позор, это последний ответ в заказе, почти не заметил - person FantomX1; 13.09.2018

Спасибо за все данные ответы.

Я преобразовал его в следующую улучшенную версию. Он устраняет необходимость в корневом префиксе, не требует использования ссылок, его легче читать, и у него лучшее имя:

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;
}
person J. Bruni    schedule 03.03.2012

Попробуй это

<?php

$data = array(
    'user' => array(
        'email'   => '[email protected]',
        '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 '[email protected]' (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)
person Basti    schedule 03.03.2012
comment
Действительно круто и полезно. Спасибо! Я предложу редактирование (я убрал необходимость установки корневого префикса). - person J. Bruni; 03.03.2012
comment
Хм, так как я не мог, я опубликую как отдельный ответ. - person J. Bruni; 03.03.2012
comment
+1 - Направил меня на правильный путь. Я бы согласился, если бы не требовался корневой префикс. - person J. Bruni; 03.03.2012
comment
немного изменил его, поэтому он не будет использовать начальный префикс. - person Basti; 03.03.2012
comment
ах неважно. это почти то же самое, что и решение Феликса Клинга. - person Basti; 03.03.2012
comment
голосование за = 10 баллов, принятие = 15 баллов; Я поблагодарил и дал баллы каждому; хотя все, что вы помогли, я приму свой собственный ответ (я не получаю баллов), потому что это код, который я действительно ИСПОЛЬЗУЮ - person J. Bruni; 03.03.2012

проверьте это здесь

я передал по ссылке, поэтому нет необходимости в возврате. просто передайте хранилище массива.

$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);
person Joseph    schedule 03.03.2012

Используйте рекурсию, например:

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;

}
person scibuff    schedule 03.03.2012
comment
Прохладный. +1 Но я не хочу указывать корневой ключ. - person J. Bruni; 03.03.2012