Golang 对相同扩展名的文件进行分组

我正在用 Golang 制作一个基本程序,它输出当前目录中的文件数以及每个文件包含多少行代码:


我现在正在尝试对具有相同扩展名的文件进行分组,但遇到了问题。所以,我所做的是将字符串映射声明为键,将字符串切片声明为值:


将 extname 作为密钥及其文件存储在该切片中


var m = make(map[string][]string)

我首先在“组”函数中收到程序读取的一段文件(q 参数),如下所示:


[.gitignore README.md cmd\root.go example.go eyeball.exe go.mod go.sum main.go utils\utils.go]


然后我对该片文件进行操作:




func group(q []string) {


    var ext string

    var checkedext []string


    for _, val := range q {

        ext = strings.Split(val, ".")[1]

        for _, foo := range q {

            secext := strings.Split(foo, ".")[1]

            if ext == secext {

                if !contains(checkedext, ext) {

                    addtogroup(ext, foo)

                    checkedext = append(checkedext, ext)

                }

            }

        }

    }

    fmt.Println(m)


}


func contains(s []string, item string) bool {

    for _, el := range s {

        if el == item {

            return true

        }

    }

    return false

}


var m = make(map[string][]string)



func addtogroup(ext, file string) {


    var subgroup []string

    if val, ok := m[ext]; ok {

       val = append(val, file)

    } else {

        subgroup = append(subgroup, file)

        m[ext] = subgroup

    }

}

当我打印地图时它输出:


map[exe:[eyeball.exe] gitignore:[.gitignore] go:[cmd\root.go] md:[README.md] mod:[go.mod] sum:[go.sum]]


但是,上面的输出是错误的,因为我有 3 个 .go 文件。


我知道范围遍历地图的副本,我不能通过指针引用它,因为地图本身就是一个引用,我找不到解决它的方法,我想这样做:


var m = make(map[string]*Data)

但我不知道这是否是最好的事情


我努力解释我希望我的程序做什么以及它做了什么,如果我遗漏了任何细节,请指出我。


Qyouu
浏览 120回答 1
1回答

心有法竹

问题是,当您将元素添加到切片(位于地图内)时,您必须重新分配结果切片,因为append()返回包含附加项的新切片标头:if val, ok := m[ext]; ok {   val = append(val, file)    m[ext] = val} else {    // ...}或者简单地说:m[ext] = append(m[ext], file)这也处理 if extis not yet in map,因为 thenm[ext]将是值类型(即[]string)的零值,而零值是nil切片。您可以附加到nil切片。另外要获得扩展名,请使用filepath.Ext().您的group()功能可以像这样简单:func group(names []string) map[string][]string {    m := map[string][]string{}    for _, name := range names {        ext := filepath.Ext(name)        ext = strings.TrimPrefix(ext, ".")        m[ext] = append(m[ext], name)    }    return m}测试它:fmt.Println(group([]string{"x\\a.txt", "b.txt", "c.go"}))fmt.Println(group([]string{"a.go", "xy\\b.go", "c.txt"}))哪些输出(在Go Playground上尝试):map[go:[c.go] txt:[x\a.txt b.txt]]map[go:[a.go xy\b.go] txt:[c.txt]]
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go