如何使用 Go 将 csv 文件按字母顺序排列?
How to alphabetize a csv file using Go?
我正在尝试使用 Go 根据第一列中的姓氏按字母顺序排列具有一系列名称的 .csv 文件。我到处搜索,但我似乎无法找到一种方法来做到这一点。有没有办法做到这一点,同时保留同一行中的其他值?
我有三个同名的 .csv 文件,但我必须将它们打乱顺序才能完成我的任务(随机 table 座位算法)。我希望能够将它们重新按定义的字母顺序排列,这样我就可以确保人们不会连续坐在一起。
提前致谢。 :)
编辑:可能值得展示我用来洗牌的功能:
func Shuffle(slice []Person) []Person {
r := rand.New(rand.NewSource(time.Now().Unix()))
ret := make([]Person, len(slice))
n := len(slice)
for i := 0; i < n; i++ {
randIndex := r.Intn(len(slice))
ret[i] = slice[randIndex]
slice = append(slice[:randIndex], slice[randIndex+1:]...)
}
return ret
Person[] 切片只是一个包含名字和姓氏的结构。
Go 的 sort
包附带一个 great example。请参阅应该可以满足您要求的修改后的实现。
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"sort"
"strings"
)
// Unsorted sample data
var unsorted = `Balaam,Wileen,Saint Louis
Meachan,Lothaire,Lefengzhen
Scoggin,Ivonne,Pag
Hawarden,Audrye,Leiria
Claypool,Biddy,Maiorca
Stanford,Douglas,Báguanos
Petriello,Yvor,Obryte
Hatter,Margette,Luoping
Pepall,Linzy,Hucun
Carter,Kit,Parungjawa
`
type Person struct {
Lastname string
Firstname string
City string
}
// Create a new Person record from a given string slice
func NewPerson(fields []string) (p Person, err error) {
if len(fields) < 3 {
return p, fmt.Errorf("not enough data for Person")
}
p.Lastname = fields[0]
p.Firstname = fields[1]
p.City = fields[2]
return
}
// ByLastname implements sort.Interface for []Person based on the Lastname field.
type ByLastname []Person
func (a ByLastname) Len() int { return len(a) }
func (a ByLastname) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByLastname) Less(i, j int) bool { return a[i].Lastname < a[j].Lastname }
func main() {
// Open unsorted CSV from string
r := csv.NewReader(strings.NewReader(unsorted))
var people []Person
for {
// Read CSV line by line
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
// Create Person from line in CSV
person, err := NewPerson(record)
if err != nil {
continue
}
people = append(people, person)
}
// Sort CSV by Lastname
sort.Sort(ByLastname(people))
// Print to stdout
for _, p := range people {
fmt.Printf("%s %s from %s\n", p.Lastname, p.Firstname, p.City)
}
// Here you would write your CSV
}
我正在尝试使用 Go 根据第一列中的姓氏按字母顺序排列具有一系列名称的 .csv 文件。我到处搜索,但我似乎无法找到一种方法来做到这一点。有没有办法做到这一点,同时保留同一行中的其他值? 我有三个同名的 .csv 文件,但我必须将它们打乱顺序才能完成我的任务(随机 table 座位算法)。我希望能够将它们重新按定义的字母顺序排列,这样我就可以确保人们不会连续坐在一起。
提前致谢。 :)
编辑:可能值得展示我用来洗牌的功能:
func Shuffle(slice []Person) []Person {
r := rand.New(rand.NewSource(time.Now().Unix()))
ret := make([]Person, len(slice))
n := len(slice)
for i := 0; i < n; i++ {
randIndex := r.Intn(len(slice))
ret[i] = slice[randIndex]
slice = append(slice[:randIndex], slice[randIndex+1:]...)
}
return ret
Person[] 切片只是一个包含名字和姓氏的结构。
Go 的 sort
包附带一个 great example。请参阅应该可以满足您要求的修改后的实现。
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"sort"
"strings"
)
// Unsorted sample data
var unsorted = `Balaam,Wileen,Saint Louis
Meachan,Lothaire,Lefengzhen
Scoggin,Ivonne,Pag
Hawarden,Audrye,Leiria
Claypool,Biddy,Maiorca
Stanford,Douglas,Báguanos
Petriello,Yvor,Obryte
Hatter,Margette,Luoping
Pepall,Linzy,Hucun
Carter,Kit,Parungjawa
`
type Person struct {
Lastname string
Firstname string
City string
}
// Create a new Person record from a given string slice
func NewPerson(fields []string) (p Person, err error) {
if len(fields) < 3 {
return p, fmt.Errorf("not enough data for Person")
}
p.Lastname = fields[0]
p.Firstname = fields[1]
p.City = fields[2]
return
}
// ByLastname implements sort.Interface for []Person based on the Lastname field.
type ByLastname []Person
func (a ByLastname) Len() int { return len(a) }
func (a ByLastname) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByLastname) Less(i, j int) bool { return a[i].Lastname < a[j].Lastname }
func main() {
// Open unsorted CSV from string
r := csv.NewReader(strings.NewReader(unsorted))
var people []Person
for {
// Read CSV line by line
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
// Create Person from line in CSV
person, err := NewPerson(record)
if err != nil {
continue
}
people = append(people, person)
}
// Sort CSV by Lastname
sort.Sort(ByLastname(people))
// Print to stdout
for _, p := range people {
fmt.Printf("%s %s from %s\n", p.Lastname, p.Firstname, p.City)
}
// Here you would write your CSV
}