扁平化多维数组并将键连接起来

32

可能重复:
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!'
);

重要提示:

  • 这些键对我非常重要。我希望它们被拼接起来,用句点分隔。

  • 它应该适用于任意层次的嵌套。

谢谢!


有几个类似的问题,但我没有找到重复的。 - J. Bruni
1
的确,有两个重复的问题。我在提问时不知道。无论如何,除了meagar的答案外,它们的所有答案都远不及现在给出的答案......它们过于复杂(使用迭代器、全局变量、类等),而实际上只需要像我们现在看到的那样简单就可以了。 - J. Bruni
5个回答

76

这样做应该可以:

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

演示


谢谢!你也有对应的吗?从这个扁平数组创建一个多维数组? - user706420
先生,谢谢您。很遗憾这是最后一个答案,我差点没注意到它。 - FantomX1

24

感谢所有给出答案的人。

我已将其转换为以下内容,这是一个改进版本。它消除了需要根前缀的需求,不需要使用引用,更易阅读,并且具有更好的名称:

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

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)

非常酷,也很有帮助。谢谢!我建议进行编辑(我删除了设置根前缀的需要)。 - J. Bruni
嗯,既然我不能这样做,那我会单独发布一个答案。 - J. Bruni
+1 - 这指引我走上了正确的道路。如果不需要根前缀,我会接受它的。 - J. Bruni
稍作修改,以避免它执行初始前缀。 - Basti
算了,这个解决方案几乎和Felix Kling的解决方案一样。 - Basti
点赞=10分,采纳=15分;我感谢并给了大家分数;虽然你们都帮助了我,但我会接受自己的答案(我不会得到分数),因为这是我实际使用的代码。 - J. Bruni

3

在这里测试php代码

我通过引用传递了值,因此不需要返回值。只需将数组存储交出即可。

$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
使用递归,如下所示:

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 但我不想指定根键。 - J. Bruni
$flattened_key = ( empty( $parent_key ) ) ? $key : $parent_key . '.' . $key; - scibuff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接