http://studygolang.com/wr?u=http%3a%2f%2f88250.b3log.org%2fgolang-ztree
package main import ( "encoding/json" "fmt" "os" "path/filepath" "sort" ) func main() { rootpath := "D:\\projects" root := FileNode{"projects", rootpath, []*FileNode{}} fileInfo, _ := os.Lstat(rootpath) walk(rootpath, fileInfo, &root) data, _ := json.Marshal(root) fmt.Printf("%s", data) } type FileNode struct { Name string `json:"name"` Path string `json:"path"` FileNodes []*FileNode `json:"children"` } func walk(path string, info os.FileInfo, node *FileNode) { // 列出当前目录下的所有目录、文件 files := listFiles(path) // 遍历这些文件 for _, filename := range files { // 拼接全路径 fpath := filepath.Join(path, filename) // 构造文件结构 fio, _ := os.Lstat(fpath) // 将当前文件作为子节点添加到目录下 child := FileNode{filename, fpath, []*FileNode{}} node.FileNodes = append(node.FileNodes, &child) // 如果遍历的当前文件是个目录,则进入该目录进行递归 if fio.IsDir() { walk(fpath, fio, &child) } } return } func listFiles(dirname string) []string { f, _ := os.Open(dirname) names, _ := f.Readdirnames(-1) f.Close() sort.Strings(names) return names }
利用自我内部循环——也就是无限递归——避免之前用那种比较傻的方式:4级菜单就用4个struct嵌套。并循环for也是4层。
if fio.IsDir() { walk(fpath, fio, &child) }
实现无限级struct嵌套,转成json,供treeview使用,即无限级树状菜单。
数据库结构用可以理解的传统的parentid,而不用那种left和right的树:https://segmentfault.com/q/1010000000126370/a-1020000000126714
好吧我忘了提一个很dirty的方法。
如果你的树深度是可预期的话,有个超简单的数据结构。你需要3个字段来表达这个树:
- id,本节点的primary key
- parent_id,其值为父节点的primary key
- key,忘了学名叫啥了,你可以称为线索
- level,表示当前节点到根节点的距离
其中,key字段的值为:从跟节点到父节点的primary key,中间用任意非数字符号分割。
例如以下树状结构
├── a │ ├── d │ │ ├── p │ │ ├── q │ │ └── r │ ├── e │ └── f ├── b │ ├── x │ ├── y │ └── z ├── c
对应的数据库表值为:
| id | value | parent_id | key | level |
| 1 | a | 0 | "-" | 1 |
| 2 | b | 0 | "-" | 1 |
| 3 | c | 0 | "-" | 2 |
| 4 | d | 1 | "1-" | 2 |
| 5 | e | 1 | "1-" | 2 |
| 6 | f | 1 | "1-" | 2 |
| 7 | x | 2 | "2-" | 2 |
| 8 | y | 2 | "2-" | 2 |
| 9 | z | 2 | "2-" | 2 |
| 10 | p | 4 | "1-4-" | 3 |
| 11 | q | 4 | "1-4-" | 3 |
| 12 | r | 4 | "1-4-" | 3 |
于是,在给定一个节点d的时候,
- 查找d的所有子孙节点:
select * from table_name where key like "${d.key}-${d.id}-%"
- 查找某个节点的所有子节点:
select * from table_name where key like "${d.key}-${d.id}-%" and level=${d.level}+1
这个设计,结构非常简单。key和level是辅助字段,维护这两个字段成本很低,即使全部重建要比MPT简单多了。
yegle的数据错了吧?根节点的 key应该是"" 吧。查找d的所有子孙节点应该是 select * from table_name where key like "${d.key}${d.id}-%" 查找子节点应该是: select * from table_name where key like "${d.key}${d.id}-%" and level=${d.level}+1
有疑问加站长微信联系(非本文作者)
Rory_Ye · 2014年06月28日