php重新格式化嵌套数组

时间:2016-12-28 14:22:47

标签: php arrays multidimensional-array

我有一个存储的无限嵌套级别数组,其中包含不需要的额外数据。

$arr = array(
    array(
        'name' => 'item1',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            'name' => 'sub-item1',
            'level' => 1,
            'extra_key' => 'some_data',
            'children' => array(
                'name' => 'sub-sub-item1',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
            array(
                'name' => 'sub-sub2-item1',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
        )
    ),
    array(
        'name' => 'item2',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            'name' => 'sub-item2',
            'level' => 2,
            'extra_key' => 'some_data',
            'children' => array(
                'name' => 'sub-sub-item2',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
            array(
                'name' => 'sub-sub2-item2',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
        )
    ),
    array(
        'name' => 'item3',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            'name' => 'sub-item3',
            'level' => 1,
            'extra_key' => 'some_data',
            'children' => array(
                'name' => 'sub-sub-item3',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
            array(
                'name' => 'sub-sub2-item3',
                'level' => 2,
                'extra_key' => 'some_data',
                'children' => array()
            ),
        )
    ),
);

预期输出数组:

$arr = array(
    array(
        'name' => 'item1',
        'nodes' => array(
            'name' => 'sub-item1',
            'nodes' => array(
                'name' => 'sub-sub-item1',
                'nodes' => array()
            ),
            array(
                'name' => 'sub-sub2-item1',
                'nodes' => array()
            ),
        )
    ),
    array(
        'name' => 'item2',
        'nodes' => array(
            'name' => 'sub-item2',
            'nodes' => array(
                'name' => 'sub-sub-item2',
                'nodes' => array()
            ),
            array(
                'name' => 'sub-sub2-item2',
                'nodes' => array()
            ),
        )
    ),
    array(
        'name' => 'item3',
        'nodes' => array(
            'name' => 'sub-item3',
            'nodes' => array(
                'name' => 'sub-sub-item3',
                'nodes' => array()
            ),
            array(
                'name' => 'sub-sub2-item3',
                'nodes' => array()
            ),
        )
    )
);

我想从所有级别移除不需要的密钥,例如levelextra_key,我还想将密钥children的名称更改为nodes,然后重现相同的密钥使用新格式的相同结构的数组。

我如何实现这一目标?

我尝试通过递归函数来完成但是我没有重现相同的结构

2 个答案:

答案 0 :(得分:1)

您的结构没有意义,可能是因为您无法编写递归函数。如果可以改变结构,我会建议这个(使用重新格式化函数实现):

<?php

$actual = array(
    array(
        'name' => 'item1',
        'level' => 0,
        'extra_key' => 'some_data',
        'children' => array(
            array(
                'name' => 'sub-item1',
                'level' => 1,
                'extra_key' => 'some_data',
                'children' => array(
                    array(
                        'name' => 'sub-sub-item1',
                        'level' => 2,
                        'extra_key' => 'some_data',
                        'children' => array()
                    ),
                    array(
                        'name' => 'sub-sub2-item1',
                        'level' => 2,
                        'extra_key' => 'some_data',
                        'children' => array()
                    ),
                )
            ),
        )
    ),
);

$expected = array(
    array(
        'name' => 'item1',
        'nodes' => array(
            array(
                'name' => 'sub-item1',
                'nodes' => array(
                    array(
                        'name' => 'sub-sub-item1',
                        'nodes' => array()
                    ),
                    array(
                        'name' => 'sub-sub2-item1',
                        'nodes' => array()
                    ),
                ),
            ),
        )
    ),
);

function change_array($original)
{
    return array_map('change_node', $original);
}

function change_node($node)
{
    return [
        'name' => $node['name'],
        'nodes' => array_map('change_node', $node['children']),
    ];
}

var_dump($expected === change_array($actual));

答案 1 :(得分:1)

此函数将以递归方式执行您想要的操作。 如果需要,您可以添加额外的排除和/或重命名的索引;

function parseArray($array): array
{
    // The resulting array
    $result          = [];
    // Indices you want renamed [`from` => `to`]
    $renameIndices   = ['children' => 'nodes'];
    // Indices you want excluded [`1`, `2`]
    $excludedIndices = ['level', 'extra_key'];
    foreach ($array as $idx => $content)
    {
        // If excluded, continue (skip) node.
        if (in_array($idx, $excludedIndices, true))
        {
            continue;
        }
        // Setting the resulting (new) index.
        $resultIdx = $idx;
        // Check if this index should be renamed
        if (array_key_exists($idx, $renameIndices))
        {
            // If index should be renamed, apply new name
            $resultIdx = $renameIndices[$idx];
        }
        // If this content block is an array. Parse it.
        if (is_array($content))
        {
            $content = parseArray($content);
        }
        // Save content to resulting array.
        $result[$resultIdx] = $content;
    }

    return $result;
}
相关问题