在查询数据库以查找嵌套在闭包表中的注释之后,比如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."
}
]
}
]
我已经破解了一个解决方案,但它似乎过于复杂,而且我觉得有一些聪明的解决方案以优雅高效的方式做到这一点,但我不知道怎么做?
答案 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);
这个解决方案需要一点点抛光。希望它有所帮助。