如何使用 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
}