Удаление структур с повторяющимися значениями полей из фрагмента структур

#loops #go #struct #duplicates

#циклы #Вперед #структура #дубликаты

Вопрос:

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

Самое близкое, к чему я пришел, — это удаление структуры из среза, если оба поля имеют то же значение, что и другая структура, но мне нужно удалить ее, если первое поле имеет то же значение, что и другая структура в срезе.

В Интернете есть много примеров выполнения этого, когда все поля в структуре имеют одинаковое значение, но я не нашел ни одного для описываемого случая.

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

Я привел упрощенный пример ниже, который подходит к сути проблемы.

Он выводит [{one 1} {one 2} {five 5}] желаемый результат [{one 1} {five 5}]

Заранее благодарю вас за помощь.

 
import "fmt"

type myKey struct {
    key string
    num int
}

type myKeysList []myKey

func remDupKeys(m myKeysList) myKeysList {
    keys := make(map[myKey]bool)
    list := myKeysList{}
    for _, entry := range m {
        if _, value := keys[entry]; !value {
            keys[entry] = true
            list = append(list, entry)
        }
    }
    return list
}
func main() {

    one := myKey{"one", 1}
    two := myKey{"one", 1}
    three := myKey{"one", 2}
    four := myKey{"one", 1}
    five := myKey{"five", 5}

    myKeysList := myKeysList{one, two, three, four, five}
    fmt.Println(myKeysList)
    uList := remDupKeys(myKeysList)
    fmt.Println(uList)
}
  

Перейти по ссылке Playground https://play.golang.org/p/x8sNjW_mxrl

Комментарии:

1. Есть ли причина, по которой это {one 1} {one 2} становится {one 1} ? Или это может стать {one 2} ? Другими словами, как бы вы отбросили структуры с одним другим полем?

2. С другой стороны, вы можете просто использовать map[string]myKey и использовать entry.key в качестве ключа карты.

3. В реальной программе второе поле представляет собой временную метку, которая преобразуется в int64 и сначала сортируется с самым старым вхождением. Было бы неплохо просто сохранить первое вхождение структуры с ключом «один» и игнорировать все остальные. Фактический вывод выглядит следующим образом dupList: [{BK048523/1 dragonfly 1605385863} {BK048523/1 dragonfly 1605385712} {BK033116/1 dragonflykings 1605383905} {BK033116/1 dragonflykings 1605383453} {BK033116/1 dragonflykings 1605383365} {BK048531/1 dragonfly 1605381867} {BK048531/1 dragonfly 1605381795}]

Ответ №1:

Основная идея вопроса верна: записывайте посещенные значения на карте и пропускайте значения, уже имеющиеся на карте.

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

 func remDupKeys(m myKeysList) myKeysList {
    keys := make(map[string]bool)
    list := myKeysList{}
    for _, entry := range m {
        if _, ok := keys[entry.key]; !ok {
            keys[entry.key] = true
            list = append(list, entry)
        }
    }
    return list
}
  

Комментарии:

1. Очень простое решение, и оно прекрасно работает. Я думал, что мне не хватает чего-то основного. Я застрял, думая, что карта должна быть того же типа, что и структура map[myKey]bool