在Go语言中按数字顺序排序文件。

huangapple go评论71阅读模式
英文:

Sorting files in numerical order in Go

问题

我正在阅读一个目录,并且我注意到如果文件按数字(1、2、3、4...)排序,它似乎使用了一些字母排序。

假设我有13个文件(命名为1.md、2.md、3.md...),排序看起来是这样的:1、10、11、12、13、2、3、4...;我目前使用的代码来产生这个顺序是:

files, _ := ioutil.ReadDir(my_dir)
for _, f := range files {
    fmt.Println(f.Name())
}

我希望的排序是1、2、3...9、10、11、12、13。

如何在这些文件上获得严格的数字排序?请注意,每个文件的名称都是N.md,其中N保证是大于或等于0的整数。

谢谢。

英文:

I am reading a directory, and with this I've noticed that if I have files which are ordered by number (1, 2, 3, 4...) then it seems to use some alphabetic ordering.

Say that I have 13 files (named 1.md, 2.md, 3.md...), the ordering would look like: 1, 10, 11, 12, 13, 2, 3, 4...; The current code I am using to produce this order is:

files, _ := ioutil.ReadDir(my_dir)
for _, f := range files {
    fmt.Println(f.Name())
}

The ordering I am looking for is 1, 2, 3, ... 9, 10, 11, 12, 13.

How can I get a strict numerical sorting on these files? Bear in mind that each file is named N.md where N is guaranteed to be an integer greater than or equal to 0.

Thank you.

答案1

得分: 10

你能实现sort接口并根据你的要求进行排序吗?给定返回的os.FileInfo元素切片,你可以使用数字顺序而不是词典顺序来排列它们。

type ByNumericalFilename []os.FileInfo

func (nf ByNumericalFilename) Len() int      { return len(nf) }
func (nf ByNumericalFilename) Swap(i, j int) { nf[i], nf[j] = nf[j], nf[i] }
func (nf ByNumericalFilename) Less(i, j int) bool {

    // 使用路径名
    pathA := nf[i].Name()
    pathB := nf[j].Name()

    // 通过解析字符串并切割扩展名来获取每个文件名的整数值
    a, err1 := strconv.ParseInt(pathA[0:strings.LastIndex(pathA, ".")], 10, 64)
    b, err2 := strconv.ParseInt(pathB[0:strings.LastIndex(pathB, ".")], 10, 64)

    // 如果有任何一个不是数字,则按词典顺序排序
    if err1 != nil || err2 != nil {
        return pathA < pathB
    }

    // 哪个整数更小?
    return a < b
}

files, _ := ioutil.ReadDir(".")

sort.Sort(ByNumericalFilename(files))

for _, f := range files {
    fmt.Println(f.Name())
}

我知道这不是非常简洁,但是是一个有效的答案。

英文:

Could you implement the sort interface and order based on your requirements? Given the slice of returned os.FileInfo elements you can arrange them using an numerical order instead of lexicographical order.

type ByNumericalFilename []os.FileInfo

func (nf ByNumericalFilename) Len() int      { return len(nf) }
func (nf ByNumericalFilename) Swap(i, j int) { nf[i], nf[j] = nf[j], nf[i] }
func (nf ByNumericalFilename) Less(i, j int) bool {

    // Use path names
    pathA := nf[i].Name()
    pathB := nf[j].Name()

    // Grab integer value of each filename by parsing the string and slicing off
    // the extension
    a, err1 := strconv.ParseInt(pathA[0:strings.LastIndex(pathA, &quot;.&quot;)], 10, 64)
    b, err2 := strconv.ParseInt(pathB[0:strings.LastIndex(pathB, &quot;.&quot;)], 10, 64)

    // If any were not numbers sort lexographically
    if err1 != nil || err2 != nil {
	    return pathA &lt; pathB
    }

    // Which integer is smaller?
    return a &lt; b
}

files, _ := ioutil.ReadDir(&quot;.&quot;)

sort.Sort(ByNumericalFilename(files))

for _, f := range files {
	fmt.Println(f.Name())
}

I know its not very concise but is a valid answer.

huangapple
  • 本文由 发表于 2015年5月9日 23:46:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/30141956.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定