go 语言,如何实现这样的嵌套循环? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
olddogs
V2EX    Go 编程语言

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

  •  
  •   olddogs 2022-05-25 19:05:50 +08:00 3845 次点击
    这是一个创建于 1285 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    "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 

    感谢!

    第 1 条附言    2022-05-25 19:50:09 +08:00

    类似这样的数据 ,

    { "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 } 
    第 2 条附言    2022-05-27 15:59:40 +08:00

    其实我就是要把数据库查出来的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 条回复    2022-05-28 13:39:15 +08:00
    iamzuoxinyu
        1
    iamzuoxinyu  
       2022-05-25 19:22:02 +08:00
    OP 表述能力堪忧……你这代码既看不出来有什么分组也看不出来有什么循环。
    lizhien
        2
    lizhien  
       2022-05-25 19:39:08 +08:00
    不知道你想说啥,不过下面的赋值用 map 不是就可以做到吗?
    olddogs
        3
    olddogs  
    OP
       2022-05-25 19:51:18 +08:00
    @iamzuoxinyu
    @lizhien

    抱歉啊,我确实没表述清楚,现在我又补了一点信息
    dcalsky
        4/span>
    dcalsky  
       2022-05-25 20:15:19 +08:00
    要先定义 struct 数据结构再解析,一直用 hashmap 可不是什么好习惯。
    olddogs
        5
    olddogs  
    OP
       2022-05-25 20:29:04 +08:00
    @dcalsky 额,多谢啊。请问能帮忙解决一下我的问题吗?
    WintersZhang
        6
    WintersZhang  
       2022-05-25 20:38:47 +08:00
    相对复杂的结构不是特别适合用 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  
       2022-05-25 20:40:51 +08:00
    emmm ,才注册不久,评论不能用 markdown ,tab 缩进也会被吃掉么...
    代码片段 OP 凑合看看吧
    seers
        8
    seers  
       2022-05-25 20:41:22 +08:00
    定义一个 children struct ,然后使用 children 数组
    olddogs
        9
    olddogs  
    OP
       2022-05-25 20:50:41 +08:00
    @WintersZhang
    @seers
    我想实现的是最上面的那个结构
    "manage": {
    "ent": {
    "export": true,
    "get": true,
    "plan": true
    }
    },
    WintersZhang
        10
    WintersZhang  
       2022-05-25 20:55:40 +08:00
    @olddogs
    php 不太懂。。
    go 的话,我觉得是一样的道理啊,把要解析的字段都定义到 struct 里,然后直接解析
    olddogs
        11
    olddogs  
    OP
       2022-05-25 21:05:44 +08:00
    @WintersZhang 试了好久,就是不行,能帮忙研究一下嘛,多谢拉
    LoNeFong
        12
    LoNeFong  
       2022-05-25 21:05:51 +08:00
    看起来就是一个链表
    iamzuoxinyu
        13
    iamzuoxinyu  
       2022-05-25 21:45:36 +08:00
    这是树状结构吧……什么奇葩设计。你是想把树状拍平么?
    6IbA2bj5ip3tK49j
        14
    6IbA2bj5ip3tK49j  
       2022-05-25 21:50:18 +08:00
    哈哈,crud ,集合操作,大道至简在这儿就不太管用了。
    olddogs
        15
    olddogs  
    OP
       2022-05-25 21:52:22 +08:00
    @iamzuoxinyu 是的,就是打算把树状拍平,有咩有办法啊? 大佬
    iamzuoxinyu
        16
    iamzuoxinyu  
       2022-05-25 21:54:10 +08:00
    @olddogs 都树状了,那就递归啊……另外我不知道你的 json 数据是谁,怎么提供的,要我就喷死设计这个接口的人。
    olddogs
        17
    olddogs  
    OP
       2022-05-25 21:57:26 +08:00
    @iamzuoxinyu 是啊,我现在就是递归,问题是,水平有限,递归不到拍平的样子 o()o
    iamzuoxinyu
        18
    iamzuoxinyu  
       2022-05-25 22:04:30 +08:00
    首先,按照 @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  
       2022-05-25 22:06:32 +08:00
    @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  
       2022-05-25 22:07:41 +08:00
    草,v2ex 的 markdown 机制好迷。
    choury
        21
    choury  
       2022-05-25 22:25:15 +08:00
    定义一个结构
    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
       2022-05-25 22:34:18 +08:00
    @iamzuoxinyu 可能理解错了吧,我是要拍平成类似链表的感觉
    iamzuoxinyu
        23
    iamzuoxinyu  
       2022-05-25 22:36:53 +08:00
    @olddogs 树状怎么可能变成链表。
    olddogs
        24
    olddogs  
    OP
       2022-05-25 22:42:17 +08:00
    @iamzuoxinyu o()o ,好吧,看来我只能换个思路了,哎,多谢了
    playniuniu
        25
    playniuniu  
       2022-05-25 23:50:50 +08:00
    完全没看明白想干啥,如果是想动态解析 json 文件,然后取得里面一些值的话,试试 gjson

    https://github.com/tidwall/gjson
    GeruzoniAnsasu
        26
    GeruzoniAnsasu  
       2022-05-26 07:20:27 +08:00
    你写的是 list 转 map

    然后你问 map 压平怎么压




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


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

    要操作树, 你肯定要会 bfs 和 dfs, 这 2 个不理解, 代码肯定不会写.
    tbxark
        31
    tbxark  
       2022-05-26 19:06:10 +08:00
    用这个 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
       2022-05-27 15:49:42 +08:00
    @playniuniu 不是想解析 json ,我贴 json ,是为了给看结构
    olddogs
        33
    olddogs  
    OP
       2022-05-27 15:52:19 +08:00
    @GeruzoniAnsasu 不是啊,其实我就是要把 sql 查出来的 List ,里面 的 key index 拼接处理成 map 的 key
    GeruzoniAnsasu
        34
    GeruzoniAnsasu  
       2022-05-27 16:28:41 +08:00
    @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  
       2022-05-27 16:30:49 +08:00
    你好像不知道你贴的所有 json 都不叫「一个列表」
    lbp0200
        36
    lbp0200  
       2022-05-27 18:58:34 +08:00
    巨婴伸手党,等着别人喂
    olddogs
        37
    olddogs  
    OP
       2022-05-28 13:07:04 +08:00
    @GeruzoniAnsasu 抱歉啊,这几天太忙了,昨天有比较急的事,搞到很晚,目标结构就是我最后一次贴的 json ,其实我现在已经换了一种方法实现了,也就是最后一次贴的代码,只是实现的比较蹩脚,我用 go 输出的树结构,然后我用 vue 拿到数据后,通过 js 的写法实现的!
    olddogs
        38
    olddogs  
    OP
       2022-05-28 13:07:42 +08:00
    @tbxark 不是的,是我最后一次贴的 json ,这个是最终要实现的
    olddogs
        39
    olddogs  
    OP
       2022-05-28 13:09:28 +08:00
    @choury 额,我要的不是一个数组,是最后一次我贴的 json ,非常感谢
    olddogs
        40
    olddogs  
    OP
       2022-05-28 13:10:36 +08:00
    @LoNeFong 类似吧
    olddogs
        41
    olddogs  
    OP
       2022-05-28 13:11:59 +08:00
    @1a7489 我现在就是给树结构到 vue ,然后用 js 处理使用,蹩脚啊!
    olddogs
        42
    olddogs  
    OP
       2022-05-28 13:14:12 +08:00
    @GeruzoniAnsasu 抱歉抱歉,你写的代码我跑了的,还有上面那个老哥的也是,非常感谢能上心我的问题
    olddogs
        43
    olddogs  
    OP
       2022-05-28 13:19:29 +08:00
    @MoYi123 表结构,就是第二个 json ,那个实际上是我已经从库里面查询出来生成的树,
    表就是以 parent_id,id ,这个父子关系来存数据的,要输出的,就是我最后一次贴的 json

    另外多谢提醒,我也是刚上手,go ,哎,抱歉抱歉,添麻烦了!
    olddogs
        44
    olddogs  
    OP
       2022-05-28 13:20:37 +08:00
    @cnbattle 通透,能传授点经验吗,大佬
    olddogs
        45
    olddogs  
    OP
       2022-05-28 13:39:15 +08:00
    @lbp0200 切莫侮辱人格,人都有难处的时候! 换位思考、换位思考,不奢望你大神能解我的难,但还希望你能管住自己的手,
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1014 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 23:32 PVG 07:32 LAX 15:32 JFK 18:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86