为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
Qyouu 2022-07-11 15:53:13
我正在用 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)但我不知道这是否是最好的事情我努力解释我希望我的程序做什么以及它做了什么,如果我遗漏了任何细节,请指出我。
查看完整描述

1 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

问题是,当您将元素添加到切片(位于地图内)时,您必须重新分配结果切片,因为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]]


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信