The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
olddogs

go 语言,如何实现这样的嵌套循环?

  •  
  •   olddogs · May 25, 2022 · 4157 views
    This topic created in 1449 days ago, the information mentioned may be changed or developed.

    请问在数据库里面查询出来的列表,如何循环出这样的分组结构呢?

    "manage": {
       "ent": {
       "export": true,
       "get": true,
       "plan": true
      }
    },
    "oa": {
       "user": {
         "add": true,
         "addDept": true,
         "addUser": true,
         "get": true,
         "plan": true
      }
    }
    

    用 php 可以通过循环,这样拼接,但是用 go 就玩不好了

    $newList[$v['name']][$v1['name']][$v2['name']] = true
    

    感谢!

    Supplement 1  ·  May 25, 2022

    类似这样的数据 ,

    {
      "id": 1,
      "name": "manage",
      "parent_id": 0,
      "children": [
        {
          "id": 101,
          "name": "ent",
          "parent_id": 1,
          "children": [
            {
              "id": 102,
              "name": "get",
              "parent_id": 101
            },
            {
              "id": 103,
              "name": "edit",
              "parent_id": 101
            }
          ]
        }
      ]
    }
    
    

    我现在的写法,但是这样有问题,这样没办法按照children分组,麻烦帮忙看看

    
    func ruleListToObj(rules []Rule) (list map[string]map[string]map[string]bool) {
    	root := make(map[string]map[string]map[string]bool)
    	module := make(map[string]map[string]bool)
    	view := make(map[string]bool)
    
    	for _, v := range rules {
    		root[v.Name] = module
    		if len(v.Children) > 0 {
    			for _, vv := range v.Children {
    				module[vv.Name] = view
    				if len(vv.Children) > 0 {
    					for _, vvv := range v.Children {
    						view[vvv.Name] = true
    					}
    				}
    			}
    		}
    	}
    	return root
    }
    
    Supplement 2  ·  May 27, 2022

    其实我就是要把数据库查出来的list,压成下面这样key value 的形式输出

    
    {
      "data": {
        "manage": {
          "ent": {
            "get": true,
            "edit": true
          },
          "app": {
            "get": true,
            "edit": true
          },
          "dept": {
            "get": true,
            "addDept": true,
            "editDept": true,
            "delDept": true,
            "addUser": true,
            "editUser": true,
            "statusUser": true
          },
          "role": {
            "get": true,
            "add": true,
            "edit": true,
            "editAuth": true,
            "del": true
          },
          "crm": {
            "get": true
          },
          "log": {
            "get": true
          },
          "setting": {
            "get": true
          }
        },
        "oa": {
          "daily": {
            "get": true
          },
          "schedule": {
            "get": true
          },
          "examine": {
            "get": true
          },
          "book": {
            "get": true
          }
        },
        "bi": {
          "datas": {
            "get": true
          },
          "visit": {
            "get": true
          }
        }
      }
    }
    
    
    45 replies    2022-05-28 13:39:15 +08:00
    iamzuoxinyu
        1
    iamzuoxinyu  
       May 25, 2022
    OP 表述能力堪忧……你这代码既看不出来有什么分组也看不出来有什么循环。
    lizhien
        2
    lizhien  
       May 25, 2022
    不知道你想说啥,不过下面的赋值用 map 不是就可以做到吗?
    olddogs
        3
    olddogs  
    OP
       May 25, 2022
    @iamzuoxinyu
    @lizhien

    抱歉啊,我确实没表述清楚,现在我又补了一点信息
    dcalsky
        4
    dcalsky  
       May 25, 2022
    要先定义 struct 数据结构再解析,一直用 hashmap 可不是什么好习惯。
    olddogs
        5
    olddogs  
    OP
       May 25, 2022
    @dcalsky 额,多谢啊。请问能帮忙解决一下我的问题吗?
    WintersZhang
        6
    WintersZhang  
       May 25, 2022
    相对复杂的结构不是特别适合用 map 来解析吧,实现定义好要解析的 json 相对应的 struct ,然后直接用 json 包的 Unmarshal 就可以了,类似这样:

    text := [你要解析的数据]

    type entry struct {
    Id int `json:"id"`
    Name string `json:"name"`
    ParentId int `json:"parent_id"`
    Children []entry `json:"children"`
    }
    e := entry{}
    json.Unmarshal([]byte(text), &e)
    WintersZhang
        7
    WintersZhang  
       May 25, 2022
    emmm ,才注册不久,评论不能用 markdown ,tab 缩进也会被吃掉么...
    代码片段 OP 凑合看看吧
    seers
        8
    seers  
       May 25, 2022
    定义一个 children struct ,然后使用 children 数组
    olddogs
        9
    olddogs  
    OP
       May 25, 2022
    @WintersZhang
    @seers
    我想实现的是最上面的那个结构
    "manage": {
    "ent": {
    "export": true,
    "get": true,
    "plan": true
    }
    },
    WintersZhang
        10
    WintersZhang  
       May 25, 2022
    @olddogs
    php 不太懂。。
    go 的话,我觉得是一样的道理啊,把要解析的字段都定义到 struct 里,然后直接解析
    olddogs
        11
    olddogs  
    OP
       May 25, 2022
    @WintersZhang 试了好久,就是不行,能帮忙研究一下嘛,多谢拉
    LoNeFong
        12
    LoNeFong  
       May 25, 2022
    看起来就是一个链表
    iamzuoxinyu
        13
    iamzuoxinyu  
       May 25, 2022
    这是树状结构吧……什么奇葩设计。你是想把树状拍平么?
    6IbA2bj5ip3tK49j
        14
    6IbA2bj5ip3tK49j  
       May 25, 2022
    哈哈,crud ,集合操作,大道至简在这儿就不太管用了。
    olddogs
        15
    olddogs  
    OP
       May 25, 2022
    @iamzuoxinyu 是的,就是打算把树状拍平,有咩有办法啊? 大佬
    iamzuoxinyu
        16
    iamzuoxinyu  
       May 25, 2022
    @olddogs 都树状了,那就递归啊……另外我不知道你的 json 数据是谁,怎么提供的,要我就喷死设计这个接口的人。
    olddogs
        17
    olddogs  
    OP
       May 25, 2022
    @iamzuoxinyu 是啊,我现在就是递归,问题是,水平有限,递归不到拍平的样子 o(╥﹏╥)o
    iamzuoxinyu
        18
    iamzuoxinyu  
       May 25, 2022
    首先,按照 @WintersZhang 给出的结构反序列化。

    ```go
    func flatten(ent *entry) []*entry {
    entries := make([]*entry, 0)
    entries = append(entries, ent)
    if len(ent.children) > 0 {
    entries = append(entries, flatten(ent.children)...)
    }
    return entries
    }
    ```

    建议补一下数据结构……
    iamzuoxinyu
        19
    iamzuoxinyu  
       May 25, 2022
    @iamzuoxinyu
    ```go
    func flatten(ent *entry) []*entry {
    entries := make([]*entry, 0)
    entries = append(entries, ent)
    for child := range ent.children {
    entries = append(entries, flatten(child)...)
    }
    return entries
    }
    ```
    iamzuoxinyu
        20
    iamzuoxinyu  
       May 25, 2022
    草,v2ex 的 markdown 机制好迷。
    choury
        21
    choury  
       May 25, 2022
    定义一个结构
    struct Child{
    Id int `json:"id"`
    Name string `json:"name"`
    ParentId int `json:"parent_id"`
    Children json.RawMessage `json:"children"`
    }

    把结果发序列化之后,把 child.Children 字段继续递归反序列化,最后存到一个数组就行了
    olddogs
        22
    olddogs  
    OP
       May 25, 2022
    @iamzuoxinyu 可能理解错了吧,我是要拍平成类似链表的感觉
    iamzuoxinyu
        23
    iamzuoxinyu  
       May 25, 2022
    @olddogs 树状怎么可能变成链表。
    olddogs
        24
    olddogs  
    OP
       May 25, 2022
    @iamzuoxinyu o(╥﹏╥)o ,好吧,看来我只能换个思路了,哎,多谢了
    playniuniu
        25
    playniuniu  
       May 25, 2022
    完全没看明白想干啥,如果是想动态解析 json 文件,然后取得里面一些值的话,试试 gjson

    https://github.com/tidwall/gjson
    GeruzoniAnsasu
        26
    GeruzoniAnsasu  
       May 26, 2022
    你写的是 list 转 map

    然后你问 map 压平怎么压




    你真的搞清楚你想问什么了????


    这个看不懂的话就没人能帮你了
    https://go.dev/play/p/oje5ib9Pu-n
    cnbattle
        27
    cnbattle  
       May 26, 2022 via Android
    List 的 key index 拼接处理成 map 的 key?
    1a7489
        29
    1a7489  
       May 26, 2022
    用 go 把 json 发送给 php 处理完了在返回 json🤣🤣🤣
    MoYi123
        30
    MoYi123  
       May 26, 2022
    能给个输入+对应的输出吗?
    给了 2 个例子, 一个没输入, 一个没期望输出.

    要操作树, 你肯定要会 bfs 和 dfs, 这 2 个不理解, 代码肯定不会写.
    tbxark
        31
    tbxark  
       May 26, 2022
    用这个 https://github.com/tidwall/gjson, 你的意思应该是根据 keypath 获取 value 吧
    ```go
    package main

    import "github.com/tidwall/gjson"

    const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`

    func main() {
    value := gjson.Get(json, "name.last")
    println(value.String())
    }
    ```
    olddogs
        32
    olddogs  
    OP
       May 27, 2022
    @playniuniu 不是想解析 json ,我贴 json ,是为了给看结构
    olddogs
        33
    olddogs  
    OP
       May 27, 2022
    @GeruzoniAnsasu 不是啊,其实我就是要把 sql 查出来的 List ,里面 的 key index 拼接处理成 map 的 key
    GeruzoniAnsasu
        34
    GeruzoniAnsasu  
       May 27, 2022
    @olddogs 你贴了 4 次代码都没解释清楚源结构是什么目标结构是什么,我真的服气。

    #15
    > 是的,就是打算把树状拍平,有咩有办法啊? 大佬

    查询出来的 list 是平坦的,你到底要从 k-v list 拼出一个树还是要把深度>1 的树平坦化成 k-v list ,至今是矛盾的。



    你给了这么多示例的 json ,全完全不提表结构是什么,最后一次贴的这有上百个不同单词的 json ,你想让别人怎么心灵感应每个单词 /字段从哪来?




    其实上面这么多回复,有灵性的早都可以想出来了

    1. 并不需要 map[string]map[string] ....,map[string]interface{} 就足够了
    2. children 这种嵌套可以用自引用模型直接在查询时查出一个嵌套的结构体
    3. 你第一条附言给的数据 flatten 的代码给你了,你试了吗
    4. gorm 的文档你好好看了吗,嵌套 preload 你看到了吗
    GeruzoniAnsasu
        35
    GeruzoniAnsasu  
       May 27, 2022
    你好像不知道你贴的所有 json 都不叫「一个列表」
    lbp0200
        36
    lbp0200  
       May 27, 2022
    巨婴伸手党,等着别人喂
    olddogs
        37
    olddogs  
    OP
       May 28, 2022
    @GeruzoniAnsasu 抱歉啊,这几天太忙了,昨天有比较急的事,搞到很晚,目标结构就是我最后一次贴的 json ,其实我现在已经换了一种方法实现了,也就是最后一次贴的代码,只是实现的比较蹩脚,我用 go 输出的树结构,然后我用 vue 拿到数据后,通过 js 的写法实现的!
    olddogs
        38
    olddogs  
    OP
       May 28, 2022
    @tbxark 不是的,是我最后一次贴的 json ,这个是最终要实现的
    olddogs
        39
    olddogs  
    OP
       May 28, 2022
    @choury 额,我要的不是一个数组,是最后一次我贴的 json ,非常感谢
    olddogs
        40
    olddogs  
    OP
       May 28, 2022
    @LoNeFong 类似吧
    olddogs
        41
    olddogs  
    OP
       May 28, 2022
    @1a7489 我现在就是给树结构到 vue ,然后用 js 处理使用,蹩脚啊!
    olddogs
        42
    olddogs  
    OP
       May 28, 2022
    @GeruzoniAnsasu 抱歉抱歉,你写的代码我跑了的,还有上面那个老哥的也是,非常感谢能上心我的问题
    olddogs
        43
    olddogs  
    OP
       May 28, 2022
    @MoYi123 表结构,就是第二个 json ,那个实际上是我已经从库里面查询出来生成的树,
    表就是以 parent_id,id ,这个父子关系来存数据的,要输出的,就是我最后一次贴的 json

    另外多谢提醒,我也是刚上手,go ,哎,抱歉抱歉,添麻烦了!
    olddogs
        44
    olddogs  
    OP
       May 28, 2022
    @cnbattle 通透,能传授点经验吗,大佬
    olddogs
        45
    olddogs  
    OP
       May 28, 2022
    @lbp0200 切莫侮辱人格,人都有难处的时候! 换位思考、换位思考,不奢望你大神能解我的难,但还希望你能管住自己的手,🙏🏻
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5457 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 126ms · UTC 05:52 · PVG 13:52 · LAX 22:52 · JFK 01:52
    ♥ Do have faith in what you're doing.