function make_tree($list,$pk='user_id',$pid='p_id',$child='_child',$root=0){
$tree=array();
foreach($list as $key=> $val){
if($val[$pid]==$root){
//获取当前$pid所有子类
unset($list[$key]);
if(! empty($list)){
$child=$this->make_tree($list,$pk,$pid,$child,$val[$pk]);
if(!empty($child)){
$val['_child']=$child;
}
}
$tree[]=$val;
}
}
return $tree;
}
参数说明:
$list 所有符合条件的分类结果集
$pk 建立关系的字段
$pid 建立关系的父ID
$child 生成子数组的键
$root 一级分类的pid值
其他方法
$cate_arr = [
['id'=>1,'name'=>'电脑','pid'=>0],
['id'=>2,'name'=>'手机','pid'=>0],
['id'=>3,'name'=>'戴尔','pid'=>1],
['id'=>4,'name'=>'联想','pid'=>1],
['id'=>5,'name'=>'苹果','pid'=>2],
['id'=>6,'name'=>'华为','pid'=>2],
['id'=>7,'name'=>'戴尔XPS','pid'=>3],
['id'=>8,'name'=>'苹果12','pid'=>5]
];
$arr = tree2($cate_arr,0);
echo "<pre>";
print_r($arr);
echo "</pre>";
//方法一
function tree($list,$pid = 0){
$tree = [];
foreach($list as $key=>$val){
if($val['pid'] == $pid){
$tree[$key] = $val;
$tree[$key]['_child']= tree($list,$val['id']);
}
}
return $tree;
}
//方法二(推荐)
function tree2($list,$pid = 0){
$tree = array();
//所有节点的子节点
$child = array();
foreach($list as $val){
$tree[$val['id']] = $val;
!isset($child[$val['id']]) && $child[$val['id']] = array();
$tree[$val['id']]['_child'] = &$child[$val['id']];
$child[$val['pid']][] = &$tree[$val['id']];
}
return $child[$pid];
}
以上是PHP版本的
JS 版本
const buildTree = (itemArray, { id = 'id', parentId = 'parentId', children = 'children', topLevelId = '0' } = {}) => {
console.log(parentId);
console.log(id);
const parentMap = new Map(); // 临时存储所有父级
const topLevelResult = []; // 存储顶层结果
for(let item of itemArray) {
if(!parentMap.has(item[id])) {
item[children] = []
} else {
item[children] = parentMap.get(item[id])[children];
}
parentMap.set(item[id], item)
if(!parentMap.has(item[parentId])) {
parentMap.set(item[parentId], {
[children]: []
});
}
parentMap.get(item[parentId])[children].push(item)
if (String(item[parentId]) === String(topLevelId)) {
topLevelResult.push(item)
}
}
return topLevelResult;
}
var List = [
{'category_id':1,'name':'11','parent_id':0},
{'category_id':2,'name':'11_1','parent_id':1}
];
json = buildTree(List,{'id':"category_id","parentId":"parent_id"});
JAVA版本
package com.example.shop.springshop;
import cn.hutool.json.JSONUtil;
import com.example.shop.springshop.bo.Person;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@SpringBootTest
public class Test {
public static List<Person> getData(boolean isSort){
Person p1 = new Person(1, 0, "顶级父1");
Person p3 = new Person(3, 1, "子1_3");
Person p4 = new Person(4, 1, "子1_4");
Person p21 = new Person(21, 3, "子1_3_21");
Person p22 = new Person(22, 4, "子1_4_22");
Person p23 = new Person(23, 4, "子1_4_23");
Person p24 = new Person(24, 23, "子1_4_23_24");
Person p5 = new Person(5, 1, "子1_5");
Person p6 = new Person(6, 1, "子1_6");
Person p7 = new Person(7, 1, "子1_7");
Person p2 = new Person(2, 0, "顶级父2");
Person p8 = new Person(8, 2, "子2_8");
Person p14 = new Person(14, 8, "子2_8_14");
Person p15 = new Person(15, 8, "子2_8_15");
Person p17 = new Person(17, 8, "子2_8_17");
Person p18 = new Person(18, 14, "子2_8_14_18");
Person p19 = new Person(19, 14, "子2_8_14_19");
Person p20 = new Person(20, 15, "子2_8_15_20");
Person p9 = new Person(9, 2, "子2_9");
Person p10 = new Person(10, 2, "子2_10");
Person p11 = new Person(11, 2, "子2_11");
Person p12 = new Person(12, 2, "子2_12");
Person p13 = new Person(13, 2, "子2_13");
Person p16 = new Person(16, 0, "顶级父16");
List<Person> list = new ArrayList<Person>();
//打乱排序
list.add(p15);
list.add(p14);
list.add(p8);
list.add(p23);
list.add(p11);
list.add(p12);
list.add(p5);
list.add(p13);
list.add(p18);
list.add(p19);
list.add(p24);
list.add(p10);
list.add(p17);
list.add(p7);
list.add(p9);
list.add(p21);
list.add(p4);
list.add(p16);
list.add(p6);
list.add(p20);
list.add(p22);
list.add(p1);
list.add(p2);
list.add(p3);
if (isSort) {
return list.stream().distinct().sorted(Comparator.comparingInt(Person::getId)).collect(Collectors.toList());
}
return list.stream().distinct().collect(Collectors.toList());
}
@org.junit.jupiter.api.Test
public void tree(){
List<Person> dataList = getData(false);
//将List转化为Map,其中id为key,对象为value
Map<Integer, Person> personMap = dataList.stream().collect(Collectors.toMap(Person::getId, Function.identity()));
//重新构建List
List<Person> list = new ArrayList<>();
//原List遍历
for (Person person : dataList) {
//获取当前对象的父级id
Integer parentId = person.getParentId();
//获取该父级id,对应的Person对象
Person parentPerson = personMap.get(parentId);
//父级对象为空,表明parentPerson为顶级父级对象,直接将其放入list:本循环运行完后,list的大小其实就是顶级父级的个数
if (parentPerson == null) {
list.add(person);
} else {
//获取父级对象的子节点
List<Person> children = parentPerson.getChildren();
//孩子节点为空,则初始化孩子节点,并将当前节点插入到父节点的孩子节点中
if (Objects.isNull(children) || children.isEmpty()) {
//初始化孩子节点
List<Person> tempList = new ArrayList<>();
tempList.add(person);
//添加到孩子节点
parentPerson.setChildren(tempList);
} else {
//孩子节点不为空,直接把当前节点插入到父级节点的子节点中
children.add(person);
}
}
}
System.out.println(list);
String s = JSONUtil.toJsonStr(list);
System.out.println(s);
}
}
//Person实体类
package com.example.shop.springshop.bo;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
@AllArgsConstructor
public class Person {
private Integer id;
private Integer parentId;
private String name;
private List<Person> children;
public Person(Integer id,Integer parentId,String name){
this.id = id;
this.parentId = parentId;
this.name = name;
}
}