Как уменьшить сложность времени при отображении структур с подрезами в go? - PullRequest
0 голосов
/ 04 апреля 2020

Скажем, есть следующая Unload структура, которая поступает как отдельный элемент ответа от микросервиса A, и где каждый Item изначально имеет пустой Units срез:

type Unload struct {
    UnloadCode   string
    Orders      []Order
}

type Order struct {
    OrderCode    string
    Items        []Item
}

type Item struct {
    ItemCode    string
    Units     []string
}

А также ItemUnit структура, которая приходит как ответ среза от микросервиса B:

type ItemUnit struct {
    ItemCode    string
    Units       []Unit
}

type Unit struct {
    UnitName    string
}

И нам нужно заполнить срез Item, Units, который соответствует UnitName значениям, на основе похожих ItemCodes с обеих сторон.

Мне удалось найти следующее решение для решения этой проблемы:

for orderIndex, order := range unload.Orders {
    for itemIndex, item := range order.Items {
        for _, itemUnit := range itemUnits {
            if item.ItemCode == itemUnit.ItemCode {
                for _, unit := range itemUnit.Units {
                    unload.Orders[orderIndex].Items[itemIndex].Units = append(unload.Orders[orderIndex].Items[itemIndex].Units, unit.UnitName)
                }
            }
        }
    }
}

Я сам не go эксперт, но мне кажется, что это решение стоит очень дорого. Был бы какой-нибудь другой, более изящный и, возможно, с меньшей временной сложностью, способ решения этой проблемы?

* Имейте в виду, что я не могу изменить структуру любой из моих структур.

1 Ответ

3 голосов
/ 04 апреля 2020

Сначала создайте карту для ItemUnit, где itemUnit.ItemCode - как ключ, а срез UnitName - как значение

    itemUnitmap := make(map[string][]string)
    for _, itemUnit := range itemUnits {
        var units []string
        for _, unit := range itemUnit.Units {
            units =  append(units, unit.UnitName)
        }
        itemUnitmap[itemUnit.ItemCode] = units
    }

. Затем используйте карту, чтобы получить срез UnitName, используя item.ItemCode. Добавьте срез в Item.Units, используя функцию variadi c

   for orderIndex, order := range unload.Orders {
        for itemIndex, item := range order.Items {
            if units, ok := itemUnitmap[item.ItemCode]; ok {
                unload.Orders[orderIndex].Items[itemIndex].Units = append(unload.Orders[orderIndex].Items[itemIndex].Units, units...)// variadic function used to append slice into slice
            }
        }
    }
...