PHP基于引用特性实现的无限级分类树
目录
无限级分类树生成可以使用递归或引用实现,但递归效率太慢,使用引用特性实现会是一个更好的方式。
源码
public function test()
{
// 初始数据
$items = array(
array('id' => 1, 'pid' => 0, 'name' => '福建省'),
array('id' => 2, 'pid' => 0, 'name' => '四川省'),
array('id' => 3, 'pid' => 1, 'name' => '福州市'),
array('id' => 4, 'pid' => 2, 'name' => '成都市'),
array('id' => 5, 'pid' => 2, 'name' => '乐山市'),
array('id' => 6, 'pid' => 4, 'name' => '成华区'),
array('id' => 7, 'pid' => 4, 'name' => '龙泉驿区'),
array('id' => 8, 'pid' => 6, 'name' => '崔家店路'),
array('id' => 9, 'pid' => 7, 'name' => '龙都南路'),
array('id' => 10, 'pid' => 8, 'name' => 'A店铺'),
array('id' => 11, 'pid' => 9, 'name' => 'B店铺'),
array('id' => 12, 'pid' => 8, 'name' => 'C店铺'),
array('id' => 13, 'pid' => 1, 'name' => '泉州市'),
array('id' => 14, 'pid' => 13, 'name' => '南安县'),
array('id' => 15, 'pid' => 13, 'name' => '惠安县'),
array('id' => 16, 'pid' => 14, 'name' => 'A镇'),
array('id' => 17, 'pid' => 14, 'name' => 'B镇'),
array('id' => 18, 'pid' => 16, 'name' => 'A村'),
array('id' => 19, 'pid' => 16, 'name' => 'B村'),
);
// 根据初始数据,生成一个以 id 为 key/下标 的数组,方便根据 pid 判断是否存在父级元素。
$items = array_column($items,null,'id');
//使用 php 的 & 引用特性,遍历一次循环即可生成无限级分类树。(其他高级语言中也有类似的特性,诸如 C++ 的指针和 JAVA 的引用)
$tree = [];
foreach ($items as $item) {
$id = $item['id'];
$pid = $item['pid'];
if (isset($items[$pid]))
$items[$pid]['children'][] = &$items[$id];
else
$tree[] = &$items[$id];
}
$this->success('ok',$tree);
}
输出
{
"code": 1,
"msg": "ok",
"data": [
{
"id": 1,
"pid": 0,
"name": "福建省",
"children": [
{
"id": 3,
"pid": 1,
"name": "福州市"
},
{
"id": 13,
"pid": 1,
"name": "泉州市",
"children": [
{
"id": 14,
"pid": 13,
"name": "南安县",
"children": [
{
"id": 16,
"pid": 14,
"name": "A镇",
"children": [
{
"id": 18,
"pid": 16,
"name": "A村"
},
{
"id": 19,
"pid": 16,
"name": "B村"
}
]
},
{
"id": 17,
"pid": 14,
"name": "B镇"
}
]
},
{
"id": 15,
"pid": 13,
"name": "惠安县"
}
]
}
]
},
{
"id": 2,
"pid": 0,
"name": "四川省",
"children": [
{
"id": 4,
"pid": 2,
"name": "成都市",
"children": [
{
"id": 6,
"pid": 4,
"name": "成华区",
"children": [
{
"id": 8,
"pid": 6,
"name": "崔家店路",
"children": [
{
"id": 10,
"pid": 8,
"name": "A店铺"
},
{
"id": 12,
"pid": 8,
"name": "C店铺"
}
]
}
]
},
{
"id": 7,
"pid": 4,
"name": "龙泉驿区",
"children": [
{
"id": 9,
"pid": 7,
"name": "龙都南路",
"children": [
{
"id": 11,
"pid": 9,
"name": "B店铺"
}
]
}
]
}
]
},
{
"id": 5,
"pid": 2,
"name": "乐山市"
}
]
}
]