-2

I have a map[string]interface{} called mapped:

mapped map[stringinterface{}

I want to iterate through it checking to see if either of these keys exist:

  • columns
  • rows

Then if so, I want to append the row or column to a slice of strings called:

  • columnOrRowArray

I understand that if I just needed to find, for example columns, within mapped I can do this:

var columnOrRowArray []string

if columnsOrRows, ok := mapped["columns"].([]interface{}); ok {
    for _, columnOrRow := range columnsOrRows {
        if columnOrRowValueIsString, ok = columnOrRow.(string); ok {
            columnOrRowArray = append(columnOrRowArray, columnOrRowValueIsString)
        }
    }
}

What would be a clean way without me duplicating the above for using row logic for the mapped["rows"]?

I want to do something that is basically this:

columnsOrRows, ok := mapped["columns"].([]interface{}) || mapped["rows"].([]interface{}); ok {

So in plain English, "if mapped has a the column or row key, assign to variable columnsOrRows"

Obviously I know the syntax for that is wrong, but I can't find an example of someone doing this

2 Answers2

3

Test for both keys:

columnsOrRows, ok := mapped["columns"].([]interface{})
if !ok {
    columnsOrRows, ok = mapped["rows"].([]interface{})
}

if ok {
    for _, columnOrRow := range columnsOrRows {
        if columnOrRowValueIsString, ok = columnOrRow.(string); ok {
            columnOrRowArray = append(columnOrRowArray, columnOrRowValueIsString)
        }
    }
}
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
1

I had to perform a broader check. Check if any of possible keys (more than 2) exist in the map. Ended up writing a utility function to accomplish the task and have the code remain readable.

func StringInSlice(s string, list []string) bool {
    for _, item := range list {
        if item == s {
            return true
        }
    }
    return false
}

func AnyKeyInMap(keys []string, keyMap map[string]interface{}) bool {
    for k := range keyMap {
        if StringInSlice(k, keys) {
            return true
        }
    }
    return false
}

The usage is:

mapped := make(map[string]interface{})
mapped["rows"] = true
if AnyKeyInMap([]string{"rows", "columns"}, mapped) {
    fmt.Println("exists")
}

You can play with it here: https://play.golang.org/p/pz64YidEGMK

Variant
  • 17,279
  • 4
  • 40
  • 65