elham anari
elham anari

Reputation: 588

Modify struct value given map of field names and values

This is my struct:

type TableFields struct {
    Name   string
    Family string
    Age    int
}

sample := TableFields{
    Name:   "bill",
    Family: "yami",
    Age:    25,
}

This is a very simple sample that I am using to describe my problem.

I want to change values in the sample struct using keys and values in a map that I receive. Each time I receive the map the keys and values will be different. How can I use the map to edit the sample struct?

For example:

updateTheseFieldsWithTheseVals := make(map[string]string)
updateTheseFieldsWithTheseVals["family"] = "yamie"
// this is my way
for key,val := range updateTheseFieldsWithTheseVals {
    // sample.Family=yamie works, but is not the answer I am looking for
    // sample.key = val  *This solution is not possible*
    oldValue := reflect.Indirect(reflect.ValueOf(get)).FieldByName(key).String()
    fmt.Println(oldValue) // result is yami

    oldValue = val
    fmt.Println(oldValue) //result is yamie
}
fmt.Println(updateTheseFieldsWithTheseVals)
// result :
// {bill yami 25}

This runs but does not change the values in sample.

Upvotes: 3

Views: 2195

Answers (1)

Thundercat
Thundercat

Reputation: 121129

Here's a function that updates string fields by name:

func update(v interface{}, updates map[string]string) {
    rv := reflect.ValueOf(v).Elem()
    for key, val := range updates {
        fv := rv.FieldByName(key)
        fv.SetString(val)
    }
}

Use it like this:

updates := map[string]string{"Family": "yamie"}
sample := TableFields{
    Name:   "bill",
    Family: "yami",
    Age:    25,
}
update(&sample, updates)

playground example

Some notes about the function:

  • The update function expects a pointer value so it can update the original value.
  • The function will panic if the field is not found or the field is not a string type. Depending on how the function is used, it may be helpful to add checks for fv.IsValid() and fv.Kind() == reflect.String.

Upvotes: 7

Related Questions