Как классифицировать список объектов на основе параметра - PullRequest
0 голосов
/ 14 января 2020

У меня есть список объектов с таким определением:

type MyObject struct {
    ID        int `json:"id"`
    Level     int `json:"level"`
    CityID    int `json:"city_id"`
}

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

Например, если у меня есть следующий список:

[
    MyObject {ID: 1, Level: 12, CityID: 7},
    MyObject {ID: 2, Level: 15, CityID: 2},
    MyObject {ID: 3, Level: 55, CityID: 4},
    MyObject {ID: 4, Level: 88, CityID: 7},
    MyObject {ID: 5, Level: 11, CityID: 4},
    MyObject {ID: 6, Level: 5, CityID: 7},
    MyObject {ID: 7, Level: 42, CityID: 2}
]

Мне нужен следующий вывод:

[
    [MyObject {ID: 1, Level: 12, CityID: 7}, MyObject {ID: 4, Level: 88, CityID: 7}, MyObject {ID: 6, Level: 5, CityID: 7}],
    [MyObject {ID: 2, Level: 15, CityID: 2}, MyObject {ID: 7, Level: 42, CityID: 2}],
    [MyObject {ID: 3, Level: 55, CityID: 4}, MyObject {ID: 5, Level: 11, CityID: 4}]
]

Я знаю, что это возможно в python используя itertools, но я новичок в go и мало знаю о его библиотеках. Любая помощь?

РЕДАКТИРОВАТЬ 1:

В настоящее время я использую это:

m := make(map[int][]MyObject)

for _, item := range myList {
    if val, ok := m[item.CityID]; ok {
        m[item.CityID] = append(val, item)
    } else {
        m[item.CityID] = []MyObject{item, }
    }
}

Ответы [ 2 ]

4 голосов
/ 14 января 2020

Ваш текущий подход - это путь к go, но он может быть упрощен, нет необходимости проверять, есть ли на карте CityID, потому что индексирует карту с ключом это не приведет к тому, что нулевое значение будет иметь тип значения, равный nil для срезов, и вы можете добавить к nil срезу без проблем:

m := make(map[int][]MyObject)

for _, item := range myList {
    m[item.CityID] = append(m[item.CityID], item)
}
0 голосов
/ 14 января 2020

Полная программа для вас

Это может быть долго, но работает нормально, может помочь, если у вас нет другого выбора.

 package main

// only needed below for sample processing

type MyObject struct {
    ID        int `json:"id"`
    Level     int `json:"level"`
    CityID    int `json:"city_id"`
}

var listOfID = make([]int, 0)

func main() {
    var listMap = make(map[int][]MyObject)

    obj :=  MyObject {ID: 1, Level: 12, CityID: 7}

    for i := 0; i < 10; i++ {
        listMap = addToList(obj, listMap)
    }

    obj1 := MyObject {ID: 1, Level: 12, CityID: 8}

    for i := 0; i < 10; i++ {
        listMap = addToList(obj1, listMap)
    }

    listOfList := getListOfLists(listMap)

    printListOfList(listOfList)
}

func printListOfList(list interface{}) {
    // print here
    return
}

func getListOfLists(listMap map[int][]MyObject) interface{} {
    var listOfLists [][]MyObject
    for i:=0; i < len(listOfID); i++ {
        innerList := listMap[listOfID[i]]
        listOfLists = append(listOfLists, innerList)
    }
    return listOfLists
}

func addToList(obj MyObject, listMap map[int][]MyObject) map[int][]MyObject {
    cityID := obj.CityID
    list := listMap[cityID]

    if list != nil {
        list = append(list, obj)
        listMap[cityID] = list
    } else {
        var newList []MyObject
        listOfID = append(listOfID, cityID)
        newList = make([]MyObject, 0)
        newList = append(newList, obj)
        listMap[cityID] = newList
    }

    return listMap
}
...