我使用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])
}
}
但是我认为这是一种非常低效的方法。那么,还有另一种方法吗?
谢谢。
使用MySQL的ORDER BY FIELD(id,'b','c','a')
是高效的,如果您不介意扩展查询并在查询中使用逻辑,那么它没有任何问题。
如果要在Go中执行此操作:Go的标准库提供了sort.Slice()
函数来对任何切片进行排序。您必须传递一个sort.Slice()
函数,该函数必须告诉切片中的2个元素如何相互关联(如果一个元素小于另一个元素)。
您需要由另一个排序的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]
})
上尝试。