【问题标题】:How to 'flatten' a multi dimensional array of unknown depth and length AND record it's parent-child relations? [closed]如何“展平”未知深度和长度的多维数组并记录它的父子关系? [关闭]
【发布时间】:2020-08-02 12:04:53
【问题描述】:

我有一个如下所示的 PHP 数组:

Array
(
    [0] => Array
        (
            [id] => 2
            [name] => Item2
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [name] => Item1
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 5
                                            [name] => Item5
                                        )
                                )
                        )
                    [1] => Array
                        (
                            [id] => 4
                            [name] => Item4
                        )
                )
        )
    [1] => Array
        (
            [id] => 3
            [name] => Item3
        )
)

它有未知(不可预测)的深度和长度。任何级别的任何项目可能有也可能没有孩子。它是从包含产品组的 xml 文件创建的。我想将其转换为包含三个元素数组的数组:id、name 和 parent id:

[0] => array('id' => '2', 'name' => 'Item2', 'parent' => 0),
[1] => array('id' => '1', 'name' => 'Item1', 'parent' => 2),
[2] => array('id' => '4', 'name' => 'Item4', 'parent' => 2) etc.

我该怎么做? 谢谢!

【问题讨论】:

  • 我投票结束这个问题,因为这读起来像是一个“谁可以为我做这件事” 的问题。您应该描述问题,更重要的是:展示您的尝试
  • 感谢您指出这一点,埃利亚斯。我使用了 for 和 foreach 循环,但觉得包含不起作用的解决方案是愚蠢的。另外,我在网上没有发现这样的问题,所以认为我的问题可能会帮助遇到同样问题的其他人。这是我在 Stackoverflow 上的第一个问题,所以我希望下次能把我的问题做得更好。

标签: php arrays multidimensional-array flatten


【解决方案1】:

这可以通过一个递归函数来实现,该函数从数组的给定级别推送所有项目,然后为任何children 数组调用自身:

function list_items($array, $parent = 0) {
    $output = array();
    foreach ($array as $arr) {
        $output[] = array('id' => $arr['id'], 'name' => $arr['name'], 'parent' => $parent);
        if (is_array($arr['children'] ?? NULL)) {
            $output = array_merge($output, list_items($arr['children'], $arr['id']));
        }
    }
    return $output;
}

$items = list_items($array);

输出(对于我稍微扩展的数据):

Array
(
    [0] => Array
        (
            [id] => 2
            [name] => Item2
            [parent] => 0
        )
    [1] => Array
        (
            [id] => 1
            [name] => Item1
            [parent] => 2
        )
    [2] => Array
        (
            [id] => 5
            [name] => Item5
            [parent] => 1
        )
    [3] => Array
        (
            [id] => 4
            [name] => Item4
            [parent] => 2
        )
    [4] => Array
        (
            [id] => 3
            [name] => Item3
            [parent] => 0
        )
)

Demo on 3v4l.org

更新

原来是数组结构不一致;当只有一个孩子时,只存储孩子的值而不是单个元素数组。这可以通过检查数组以查看是否设置了 id (Ид) 元素来处理,如果是,则在处理之前将数组推深一层:

function list_items($array, $parent = 0) {
    $output = array();
    if (isset($array['Ид'])) {
        $array = array($array);
    }
    foreach ($array as $arr) {
        if (!is_array($arr)) echo $arr;
        $output[] = array('id' => $arr['Ид'], 'name' => $arr['Наименование'], 'parent' => $parent);
        if (is_array($arr['Группы']['Группа'] ?? NULL)) {
            $output = array_merge($output, list_items($arr['Группы']['Группа'], $arr['Ид']));
        }
    }
    return $output;
}

$items = list_items($array);
print_r($items);

Demo on 3v4l.org

【讨论】:

  • 太棒了!谢谢你尼克!有些东西我不明白 - 一些输出名称有错误:一个名称是“6。项目名称”,它只给了我 6,另一个是“Журналы учета”(虽然所有名称都是西里尔文),它给了我我是一个奇怪的符号我还有一个子元素,名称和 ID 都带有字母“f”,作为某个父级的第二个子级,而父级在原始数组中有一个子级。
  • @tolkodelo 很奇怪。您能否使用显示问题的数据修改我的演示?然后我可以尝试修复它。
  • @tolkodelo 这些名字本身不是问题:3v4l.org/Qh28c 你确定数组的格式正确吗?
  • 我尝试将整个数组添加到您的示例中,但显示为“413 请求实体太大”。想在真实条件下尝试,所以我没有缩短它。我已经把数组做成文件上传到yadi.sk/d/vPiqZkRsWQqw_A用phpstorm打开,没有发现错误,所以数组一定要正确形成。
  • 如果我尝试下载该文件,则会收到错误消息(“现在无法下载该文件”)。你可以试试 pastebin 吗?
猜你喜欢
  • 2013-07-12
  • 1970-01-01
  • 2015-04-20
  • 2022-01-24
  • 2013-10-29
  • 2017-07-03
  • 2012-06-07
  • 2014-11-20
  • 1970-01-01
相关资源
最近更新 更多