使用Go递归打印树状结构的完整列表时遇到一些问题

问题描述 投票:2回答:1

我在为具有nth命令的CLI工具创建结构时遇到麻烦。每个命令可以具有nth个子命令,每个子命令可以具有nth个更多子命令。

我当前的问题是,我一直在努力寻找一种创建递归函数的方法,以输出每个命令的名称以及每个nth子命令+每个nth子命令对于该子命令,在完整列表中。

例如,我正在寻找以下输出:

1. command1
2. command2
3. command3
4. command3 subcommand1
5. command3 subcommand1 subcommand1
6. command3 subcommand2

这是我当前的代码:

package main

import (
    "fmt"
)

type command struct {
    name        string
    parent      *command
    subcommands []*command
}

func getLastCommand(c command) command {
    for _, s := range c.subcommands {
        if len(s.subcommands) == 0 {
            return *s
        }
        return getLastCommand(*s)
    }
    return c
}

func main() {
    cmdBase1 := command{
        name: "base1",
    }

    cmdBase2 := command{
        name: "base2",
    }

    var (
        cmdBase3,
        cmdBase3Sub1,
        cmdBase3Sub1Sub1,
        cmdBase3Sub2 command
    )

    cmdBase3 = command{
        name:        "base3",
        subcommands: []*command{&cmdBase3Sub1, &cmdBase3Sub2},
    }

    cmdBase3Sub1 = command{
        name:        "base3:sub1",
        parent:      &cmdBase3,
        subcommands: []*command{&cmdBase3Sub1Sub1},
    }

    cmdBase3Sub1Sub1 = command{
        name:   "base3:sub1:sub1",
        parent: &cmdBase3Sub1,
    }

    cmdBase3Sub2 = command{
        name:   "base3:sub2",
        parent: &cmdBase3,
    }

    // root commands
    commands := []command{
        cmdBase1,
        cmdBase2,
        cmdBase3,
    }

    for _, c := range commands {
        last := getLastCommand(c)
        fmt.Println(last.name)
    }
}

https://play.golang.org/p/HZPRlSghfAY

这里是当前输出:

base1
base2
base3:sub1:sub1

我想要的输出是上面的代码是:

base1
base2
base3
base3:sub1
base3:sub1:sub1
base3:sub2

我需要在代码中进行哪些更改,以便获得高于期望的输出?有没有我可以遵循的算法或数据结构来解决这个问题?我尝试了深度优先和二进制搜索,但似乎无法将其塑造到我的结构中。

go recursion struct slice
1个回答
1
投票

一个简单而优雅的解决方案是使用command方法“武装” print()。这可以打印其名称,并覆盖其子命令,并调用其print()(执行相同的操作):

func (c *command) print() {
    fmt.Println(c.name)
    for _, sc := range c.subcommands {
        sc.print()
    }
}

然后在main()中打印命令只是调用其print()方法(甚至不需要/使用getLastCommand():]

for _, c := range commands {
    c.print()
}

这将产生所需的输出(在Go Playground上尝试):

base1
base2
base3
base3:sub1
base3:sub1:sub1
base3:sub2
© www.soinside.com 2019 - 2024. All rights reserved.