Merging 2 slices from a method into a map

Issue

I have a function that returns 2 variables in a form of slices and I want to merge the two slices into a map as key-value pairs. The issue is that can’t find a way to iterate through each slice separately and add them as a key and a value.
The current implementation is iterating through all the prices and it’s adding every price to the town key.

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    cities, prices := citiesAndPrices()
    towns := groupSlices(cities, prices)
    for cities := range towns {

        fmt.Println(cities, prices)
    }

}

func citiesAndPrices() ([]string, []int) {
    rand.Seed(time.Now().UnixMilli())
    cityChoices := []string{"Berlin", "Moscow", "Chicago", "Tokyo", "London"}
    dataPointCount := 100
    cities := make([]string, dataPointCount)
    for i := range cities {
        cities[i] = cityChoices[rand.Intn(len(cityChoices))]
    }
    prices := make([]int, dataPointCount) 
    for i := range prices {
        prices[i] = rand.Intn(100)
    }
    return cities, prices
}

func groupSlices([]string, []int) map[string]int {
    cities, prices := citiesAndPrices()
    towns := make(map[string]int)
    for _, cities := range cities {
        for _, prices := range prices {
            towns[cities] = prices
            break
        }
    }
    return towns
}

Solution

You must return groupSlice function as map[string][]int

This is a tips for you:

Seed, unlike the Rand.Seed method, is safe for concurrent use. source.

So You can call it once, not on every call function. This will speed up your app.

I think this is the code that what you want.

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    cities, prices := citiesAndPrices()
    towns := groupSlices(cities, prices)
    fmt.Println()
    total := 0
    for c, p := range towns {
        fmt.Println(c, p)
        total += len(p)
    }
    fmt.Println()
    fmt.Println("total must 200, found :", total) // total must be 200
}

func citiesAndPrices() ([]string, []int) {
    cityChoices := []string{"Berlin", "Moscow", "Chicago", "Tokyo", "London"}
    dataPointCount := 100
    cities := make([]string, dataPointCount)
    prices := make([]int, dataPointCount)
    for i := range cities {
        cities[i] = cityChoices[rand.Intn(len(cityChoices))]
        prices[i] = rand.Intn(100)
    }
    fmt.Println("inside citiesAndPrices func")
    fmt.Println(cities)
    fmt.Println(prices)
    fmt.Println("done run citiesAndPrices func\n")
    return cities, prices
}

func groupSlices(c1 []string, p1 []int) map[string][]int {
    c2, p2 := citiesAndPrices()
    towns := make(map[string][]int)
    for i, t := range c1 {
        // this is for cities1 and price1
        if towns[t] == nil {
            towns[t] = make([]int, 0)
        }
        towns[t] = append(towns[t], p1[i])

        // this is for cities2 and price2
        if towns[c2[i]] == nil {
            towns[c2[i]] = make([]int, 0)
        }
        towns[c2[i]] = append(towns[c2[i]], p2[i])
    }
    return towns
}

Answered By – Rahmat Fathoni

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.