我使用Go和MySQL数据库。假设我有一片像这样的字符串:[]string{"b", "c", "a"}
,并且我想要这样的最终数据:
[]Student{
Student{ID: "b", Name: "Ben"},
Student{ID: "c", Name: "Carl"},
Student{ID: "a", Name: "Alexander"},
}
当我要构建MySQL查询时,使用ORDER BY FIELD(id,'b','c','a')
是一种有效的方法吗?或者,如果我不使用它,我将有如下代码:
keys := []string{"b", "c", "a"}
...
students := make([]Student, 0)
for rows.Next() {
s := Student{}
err := rows.Scan(&s.ID, &s.Name)
if err != nil {
log.Fatal(err)
}
students = append(students, s)
}
mStudents := make(map[string]Student, 0)
for _, v := range students {
mStudents[v.ID] = v
}
finalData := make([]Student, 0)
for _, v := range keys {
if _, ok := mStudents[v]; ok {
finalData = append(finalData, mStudents[v])
}
}
但是我认为这是一种非常低效的方法。那么,还有另一种方法吗?
谢谢。
答案 0 :(得分:2)
使用MySQL的ORDER BY FIELD(id,'b','c','a')
效率很高,如果您不介意扩展查询并在查询中加入逻辑,那么这没什么问题。
如果要在Go中执行此操作:Go的标准库提供了sort.Slice()
函数来对任何切片进行排序。您必须向其传递一个less()
函数,该函数必须告诉切片中的两个元素如何相互关联(如果一个元素小于另一个元素的话)。
您想要由另一个排序的keys
切片指定的订单。因此,基本上要判断一个学生是否比另一个学生“少”,您需要比较其键的索引。
为避免每次都必须线性搜索键片,您应该构建一个键图:
m := map[string]int{}
for i, k := range keys {
m[k] = i
}
因此,作为“较少”逻辑基础的索引是一个简单的地图查找:
sort.Slice(students, func(i, j int) bool {
return m[students[i].ID] < m[students[j].ID]
})
在Go Playground上尝试一下。