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.
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, ".")], 10, 64)
b, err2 := strconv.ParseInt(pathB[0:strings.LastIndex(pathB, ".")], 10, 64)
// If any were not numbers sort lexographically
if err1 != nil || err2 != nil {
return pathA < pathB
}
// Which integer is smaller?
return a < b
}
files, _ := ioutil.ReadDir(".")
sort.Sort(ByNumericalFilename(files))
for _, f := range files {
fmt.Println(f.Name())
}
I know its not very concise but is a valid answer.