Сортировка среза по порядку элементов в другом срезе - PullRequest
0 голосов
/ 29 мая 2019

Я пытаюсь упорядочить фрагмент на основе порядка элементов в другом фрагменте.Моя функция сортировки работает, когда у меня есть только один из каждого типа в моем срезе, который я хочу заказать, однако, когда я начинаю добавлять больше элементов, порядок прерывается.

Я создал пример на игровой площадке Golang.

https://play.golang.org/p/e9sHIeV2qSf

Я хочу упорядочить свой вариантный срез в поле Код и сделать его таким же, как и порядоккоды отображаются в структуре Language.

Ниже приведена функция сортировки, которую я использую:

sort.Slice(variants, func(i, j int) bool {
    for k, language := range languages {
        if language.Code == variants[i].Code {
            return i >= k
        }
    }

    return false
})

Текущий порядок возврата:

Сортированный фрагмент: [{Код: en-GB} {Код: en-US} {Код: en-GB} {Код: es-ES} {Код: en-GB} {Код: en-GB} {Код: en-GB} {Код: en-GB} {Код: es-ES}]

Когда порядок в моей структуре Language:

"en-GB", "en-US "," fr-FR "," es-ES "

1 Ответ

1 голос
/ 29 мая 2019

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

var langMap map[string]int
for i, lang := range languages {
    langMap[lang.Code] = i
}

С этим становится просто просто посмотреть рейтинг каждого элемента в variants и вернутьсясоответствующее значение:

sort.Slice(variants, func(i, j int) bool {
    iRank, jRank := langMap[variants[i].Code], langMap[variants[j].Code]
    return iRank < jRank
})

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

sort.Slice(variants, func(i, j int) bool {
    iRank, iExists := langMap[variants[i].Code]
    jRank, jExists := langMap[variants[j].Code]
    switch (
    case iExists && jExists:
        // Both exist in the pre-ordered list, so sort by rank
        return iRank < jRank
    case !iExists && !jExists:
        // Neither exists in the pre-ordered list, sort alphabetically
        return variants[i].Code < variants[j].Code
    case iExists:
        // Only i exists, so sort it before j
        return true
    default: // jExists
        // Only j exists, so sort it after i
        return false
    )

})

Это логически возможносделать то же самое, просматривая список ссылок каждый раз, когда вы пытаетесь, но об этом гораздо сложнее думать и гораздо менее эффективно.

...