String 使用Golang对文件名中带有数字的字符串进行排序
我正在尝试将一些旧的python代码转换成Go-lang。但是我在文件夹中对文件进行排序时遇到了困难。由于文件总是String 使用Golang对文件名中带有数字的字符串进行排序,string,sorting,go,numbers,String,Sorting,Go,Numbers,我正在尝试将一些旧的python代码转换成Go-lang。但是我在文件夹中对文件进行排序时遇到了困难。由于文件总是AMA1.txt,AMA2.txt等。在python源代码中,我这样做: files=[] for file in os.listdir(someDir): if file.endswith(".txt"): files.append(file) convert = lambda text: int(text) if text.isdigit() else t
AMA1.txt
,AMA2.txt
等。在python源代码中,我这样做:
files=[]
for file in os.listdir(someDir):
if file.endswith(".txt"):
files.append(file)
convert = lambda text: int(text) if text.isdigit() else text
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)',key) ]
files.sort( key=alphanum_key )
for i in files:
print (i)
我到目前为止,但错过了分类:
func main() {
dirname := "someDir"
d, err := os.Open(dirname)
if err != nil {
fmt.Println(err)
}
defer d.Close()
fi, err := d.Readdir(-1)
if err != nil {
fmt.Println(err)
}
for _, fi := range fi {
if fi.Mode().IsRegular() {
fmt.Println(fi.Name())
}
}
}
将每个项目收集到一个切片中,然后对其进行排序。包文档中有示例和说明 在您的情况下,在排序之前提取数字可能更容易。对于这一点,这很有用。围棋有一个很好的选择。从具有非负整数后缀的名称构造可排序名称 比如说,
package main
import (
"encoding/binary"
"fmt"
"os"
"path/filepath"
"sort"
"strconv"
)
// sortName returns a filename sort key with
// non-negative integer suffixes in numeric order.
// For example, amt, amt0, amt2, amt10, amt099, amt100, ...
func sortName(filename string) string {
ext := filepath.Ext(filename)
name := filename[:len(filename)-len(ext)]
// split numeric suffix
i := len(name) - 1
for ; i >= 0; i-- {
if '0' > name[i] || name[i] > '9' {
break
}
}
i++
// string numeric suffix to uint64 bytes
// empty string is zero, so integers are plus one
b64 := make([]byte, 64/8)
s64 := name[i:]
if len(s64) > 0 {
u64, err := strconv.ParseUint(s64, 10, 64)
if err == nil {
binary.BigEndian.PutUint64(b64, u64+1)
}
}
// prefix + numeric-suffix + ext
return name[:i] + string(b64) + ext
}
func main() {
dirname := "someDir"
d, err := os.Open(dirname)
if err != nil {
fmt.Println(err)
return
}
defer d.Close()
fi, err := d.Readdir(-1)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("\nUnsorted:")
for _, fi := range fi {
if fi.Mode().IsRegular() {
fmt.Println(fi.Name())
}
}
sort.Slice(
fi,
func(i, j int) bool {
return sortName(fi[i].Name()) < sortName(fi[j].Name())
},
)
fmt.Println("\nSorted:")
for _, fi := range fi {
if fi.Mode().IsRegular() {
fmt.Println(fi.Name())
}
}
}
很有魅力。与python相比,有相当多的代码,但go在其他领域的简单性仍然使其成为我的新选择武器。:-)
Unsorted:
amt099.txt
amt.txt
amt2.txt
amt100.txt
amt10.txt
amt1.txt
Sorted:
amt.txt
amt1.txt
amt2.txt
amt10.txt
amt099.txt
amt100.txt