概述
使用PHP将数据组装成树状结构,相当简单,因为没有类型的转化限制等,数组即一切,而使用GO语言编写成较为通用的代码,相对要繁琐一些,本文为包含了PHP及GO相关代码
php组织分类树,一个函数搞定
//本函数通过对地址的充分使用,只用一层循环,便完成了对所有数据的树状结构组织。
//id 数据主键
//parent_id 父级数据主键
public static function makeTree($records)
{
$tree = [];
$data = [];
foreach ($records as $item) {
$item['children'] = [];
$data[$item['id']] = $item;
}
foreach ($data as $item) {
if ($item['parent_id'] != 0 && isset($data[$item['parent_id']])) {
$data[$item['parent_id']]['children'][] = &$data[$item['id']];
} else {
$tree[] = &$data[$item['id']];
}
}
return $tree;
}
使用go完成相应功能,要使用到接口
- 接口定义,组织树状结构的方法,需要使用到此接口内的相关方法
type NodeWithChildren interface {
GetID() int
GetParentID() int
GetChildren() []NodeWithChildren
SetChildren(children []NodeWithChildren)
}
2.方法
func BuildTree(nodes []NodeWithChildren) []NodeWithChildren {
nodeMap := make(map[int]NodeWithChildren)
// 将所有节点放入 map 中,以 ID 作为 key
for _, node := range nodes {
nodeMap[node.GetID()] = node
}
// 遍历节点,根据 ParentID 将子节点连接到对应的父节点上
var rootNodes []NodeWithChildren
for _, node := range nodes {
parentID := node.GetParentID()
if parentID == 0 {
rootNodes = append(rootNodes, node)
} else {
parent, ok := nodeMap[parentID]
if ok {
children := parent.GetChildren()
children = append(children, node.(NodeWithChildren))
parent.SetChildren(children)
}
}
}
return rootNodes
}
3.使用此方法的结构体,必须实现接口所有方法,例
//以下为要组织成树状结构的结构体
type ArticleCategory struct {
ID int `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"`
Pid int `gorm:"column:pid;not null" json:"pid"`
Name string `gorm:"column:name;not null" json:"name"`
Intro string `gorm:"column:intro" json:"intro"`
Sort int32 `gorm:"column:sort;not null" json:"sort"`
Cover string `gorm:"column:cover" json:"cover"`
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at" json:"deleted_at"`
Children []NodeWithChildren `gorm:"-"`//此处表示不从数据库中查找此字段
}
func (c *ArticleCategory ) GetID() int {
return c.ID
}
func (c *ArticleCategory ) GetParentID() int {
return c.Pid
}
func (c *ArticleCategory ) GetChildren() []NodeWithChildren {
return c.Children
}
func (c *ArticleCategory ) SetChildren(children []NodeWithChildren) {
c.Children = children
}
func (c *ArticleCategory ) MakeTree(records []ArticleCategory ) []NodeWithChildren {
var convertedNodes []NodeWithChildren
for _, category := range records {//这一步很关键,此处将数据转换为NodeWithChildren
cat := category
convertedNodes = append(convertedNodes, &cat)
}
return BuildTree(convertedNodes)
}
4.打印树结构
func PrintTree(trees interface{}) {
b, _ := json.MarshalIndent(trees, "", " ")
fmt.Println(string(b))
}
4.使用gorm获取数据并进行测试
var DB *gorm.DB
func initDb() {
var err error
DB, err = gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true, //英语单数形式
},
})
//gorm.Open(cfg.Driver, cfg.Source)
DB = DB.Debug() //调式模式
if err != nil {
panic("数据库连接失败:" + err.Error())
}
}
func main() {
initDb()
var mts []ArticleCategory
err := DB.Model(&ArticleCategory {}).Find(&mts).Error
if err != nil {
panic(err)
}
article := dao.ArticleCategory {}
tree := article .MakeTree(mts)
PrintTree(tree)//打印树
}
以上,记录php及go生成树状结构的相关思路