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

Возможный дубликат:
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!'
);

Важный:

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

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

Спасибо!

19

Решение

Примерно так должно работать:

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

DEMO

57

Другие решения

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

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

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

Попробуй это

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

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

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;

}
1

проверить это Вот

Я прошел по ссылке, так что нет необходимости для возврата. просто сдайте массив хранения.

$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);
1
По вопросам рекламы [email protected]