Сортировка данных в соответствии с последовательностью ключей в срезе Go - PullRequest
0 голосов
/ 25 февраля 2020

Я работаю с базами данных 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])
   }
}

Но я думаю, что это очень неэффективный способ. Итак, есть ли другой способ?

Спасибо.

1 Ответ

2 голосов
/ 25 февраля 2020

Использование MySQL ORDER BY FIELD(id,'b','c','a') эффективно, и в этом нет ничего плохого, если вы не возражаете против необходимости расширять запрос и иметь свои логики c в запросе.

Если вы хотите сделать это в стандартной библиотеке Go: Go предоставляет функцию sort.Slice() для сортировки любого фрагмента. Вы должны передать ей функцию less(), которая должна указать, как 2 элемента в срезе коррелируют друг с другом, если один меньше другого.

Требуется порядок, обозначенный другим, отсортированный keys кусочек. Таким образом, чтобы определить, является ли один ученик «меньше» другого, вам нужно сравнить индексы их ключей.

Чтобы избежать необходимости линейного поиска среза ключей каждый раз, вы должны построить карту их :

m := map[string]int{}
for i, k := range keys {
    m[k] = i
}

Итак, индекс, являющийся базой логики "less" c, является простым поиском карты:

sort.Slice(students, func(i, j int) bool {
    return m[students[i].ID] < m[students[j].ID]
})

Попробуйте это на Go Детская площадка .

...