Using "dynamic" key to extract value from map

Issue

Came from javascript background, and just started with Golang. I am learning all the new terms in Golang, and creating new question because I cannot find the answer I need (probably due to lack of knowledge of terms to search for)

I created a custom type, created an array of types, and I want to create a function where I can retrieve all the values of a specific key, and return an array of all the values (brands in this example)

type Car struct {
  brand string
  units int
}

....

var cars []Car
var singleCar Car

//So i have a loop here and inside the for-loop, i create many single cars
singleCar = Car {
   brand: "Mercedes",
   units: 20
}

//and i append the singleCar into cars
cars = append(cars, singleCar)

Now what I want to do is to create a function that I can retrieve all the brands, and I tried doing the following. I intend to have key as a dynamic value, so I can search by specific key, e.g. brand, model, capacity etc.

func getUniqueByKey(v []Car, key string) []string {
    var combined []string

    for i := range v {
        combined = append(combined, v[i][key]) 
        //this line returns error -
        //invalid operation: cannot index v[i] (map index expression of type Car)compilerNonIndexableOperand
    }
    return combined
    //This is suppose to return ["Mercedes", "Honda", "Ferrari"]
}

The above function is suppose to work if i use getUniqueByKey(cars, "brand") where in this example, brand is the key. But I do not know the syntaxes so it’s returning error.

Solution

Seems like you’re trying to get a property using a slice accessor, which doesn’t work in Go. You’d need to write a function for each property. Here’s an example with the brands:

func getUniqueBrands(v []Car) []string {
    var combined []string
    tempMap := make(map[string]bool)

    for _, c := range v {
        if _, p := tempMap[c.brand]; !p {
            tempMap[c.brand] = true
            combined = append(combined, c.brand)
        }
    }
    return combined
}

Also, note the for loop being used to get the value of Car here. Go’s range can be used to iterate over just indices or both indices and values. The index is discarded by assigning to _.

I would recommend re-using this code with an added switch-case block to get the result you want. If you need to return multiple types, use interface{} and type assertion.

Answered By – Emily

Answer Checked By – Mary Flores (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.