如何从DB中创建平面数组的嵌套注释数组

时间:2013-10-13 18:28:28

标签: php sql arrays hierarchical-data

在查询数据库以查找嵌套在闭包表中的注释之后,比如Bill Karwin在此建议What is the most efficient/elegant way to parse a flat table into a tree?,我现在从SQL获得以下数据结构:

"comments": [
            {
                "id": "1",
                "breadcrumbs": "1",
                "body": "Bell pepper melon mung."
            },
            {
                "id": "2",
                "breadcrumbs": "1,2",
                "body": "Pea sprouts green bean."
            },
            {
                "id": "3",
                "breadcrumbs": "1,3",
                "body": "Komatsuna plantain spinach sorrel."
            },
            {
                "id": "4",
                "breadcrumbs": "1,2,4",
                "body": "Rock melon grape parsnip."
            },
            {
                "id": "5",
                "breadcrumbs": "5",
                "body": "Ricebean spring onion grape."
            },
            {
                "id": "6",
                "breadcrumbs": "5,6",
                "body": "Chestnut kohlrabi parsnip daikon."
            }
        ]

使用PHP我想重构这个数据集,因此注释嵌套如下:

"comments": [
            {
                "id": "1",
                "breadcrumbs": "1",
                "body": "Bell pepper melon mung."
                "comments": [
                    {
                        "id": "2",
                        "breadcrumbs": "1,2",
                        "body": "Pea sprouts green bean."
                        "comments": [
                            {
                                "id": "4",
                                "breadcrumbs": "1,2,4",
                                "body": "Rock melon grape parsnip."
                            }
                        ]
                    },
                    {
                        "id": "3",
                        "breadcrumbs": "1,3",
                        "body": "Komatsuna plantain spinach sorrel."
                    }
                ]
            },
            {
                "id": "5",
                "breadcrumbs": "5",
                "body": "Ricebean spring onion grape."
                "comments": [
                    {
                        "id": "6",
                        "breadcrumbs": "5,6",
                        "body": "Chestnut kohlrabi parsnip daikon."
                    }
                ]
            }
        ]

我已经破解了一个解决方案,但它似乎过于复杂,而且我觉得有一些聪明的解决方案以优雅高效的方式做到这一点,但我不知道怎么做?

3 个答案:

答案 0 :(得分:1)

假设您将所有数据提取到由“id”索引的数组中:

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $nodes[$row["id"]] = $row;
}

我测试了以下内容,它可以生成您想要的JSON输出:

foreach ($nodes as &$node) {
        $parent = array_shift(array_slice(explode(",",$node["breadcrumbs"]), -2, 1));
        if ($parent == $node["id"]) {
                $forest["comments"][] = &$node;
        } else {
                $nodes[$parent]["comments"][] = &$node;
        }
}

print json_encode($forest, JSON_PRETTY_PRINT);

答案 1 :(得分:0)

我建议采用两阶段方法。 第1阶段:构建嵌套数组 第2阶段:将数组转换为JSON

只需通过基于面包屑创建元素即可处理第1阶段。 例如,对于“breadcrumbs”:“1,2,4”

$comments_array[1][2][4] = $current_element_from_flat_array;

我不确定获得上述代码的最优雅方式是,通过将面包屑解析为其元素并在其中使用if-else语句。它可能是功能性的,但它可能不是最优雅的代码。

$breadcrumbs_list = explode(",", $pizza);
if (count($breadcrumbs_list) == 2)
    $comments_array[$breadcrumbs_list[1]][$breadcrumbs_list[2]] = $current_element_from_flat_array;
else if (count($breadcrumbs_list) == 3)
    $comments_array[$breadcrumbs_list[1]][$breadcrumbs_list[2]][$breadcrumbs_list[1]] = $current_element_from_flat_array;

第2阶段可以使用PHP提供的json_encode()来完成。

答案 2 :(得分:0)

$tree = array('NULL' => array('children' => array()));
 foreach($array as $item){
    if(isset($tree[$item['id']])){
       $tree[$item['id']] = array_merge($tree[$item['id']],$item);
    } else {
       $tree[$item['id']] = $item;
    }

    $parentid = is_null($item['id_parent']) ? 'NULL' : $item['id_parent'];
    if(!isset($tree[$parentid])) $tree[$parentid] = array('children' => array());
    //this & is where the magic happens: any alteration to $tree[$item['id']
    //  will reflect in the item $tree[$parentid]['children'] as they are the same
    //  variable. For instance, adding a child to $tree[$item['id']]['children]
    //  will be seen in 
    //  $tree[$parentid]['children'][<whatever index $item['id'] has>]['children]
    $tree[$parentid]['children'][] = &$tree[$item['id']];
 }
 $result = $tree['NULL']['children'];
 //always unset references
 unset($tree);

这个解决方案需要一点点抛光。希望它有所帮助。