Venkat
Venkat

Reputation: 81

golang - converting [ ]Interface to [ ]strings or joined string

How can I convert []interface to []strings or just as a joined single string with all elements in []interface ? Below is the screenshot showing exact value of "scope" which of type []interface with length of 2. In below code, where case is "slice" Currently i am doing this using reflect but this is not looking good. Wondering there should be some good way to join a slice\array of interface elements.

I also did try using json unmarshall like this "json.Unmarshal([]byte(jwtResp),&mymap)" but having trouble with type issues in converting jwt.MapClaims to byte[]

parsedkey, _ := jwt.ParseRSAPublicKeyFromPEM([]byte(key))
parsedToken, jwtErr := jwt.Parse(bearerToken, func(token *jwt.Token) (interface{}, error) {
    return parsedkey, nil
})
jwtValues = make(map[string]string)
// we dont know which data types we are dealing with here, so using swtich case based on value data type
jwtResp := parsedToken.Claims.(jwt.MapClaims)
    for k, v := range jwtResp {
        switch reflect.TypeOf(v).Kind() {

        case reflect.Slice:
            fmt.Println("tp is : ", reflect.TypeOf(v)) // this is []interface{}
            fmt.Println("type is : ", reflect.TypeOf(v).Kind()) // this is slice
            s := reflect.ValueOf(v)
            for i := 0; i < s.Len(); i++ {
                jwtValues[k] += s.Index(i).Interface().(string)
                jwtValues[k] += "|"
            }

        case reflect.String:
            jwtValues[k] = v.(string)

        default:
            fmt.Println("unknown datatype")
        }
    }

enter image description here

Upvotes: 0

Views: 1595

Answers (2)

Venkat
Venkat

Reputation: 81

Thanks for the suggestions . Below is the closest solution i found replacing 'switch' with 'if' condition along with type assertions. 'reflect' is costly. Using below code, i am finding if values of jwtResp is a slice, or string or something else. If slice, traverse through the values([]interface with string type elements) and join those as one concatenated string.

for k, v := range jwtResp {
        if s, ok := v.(string); ok {
                JwtValues[k] = s
            } else if s, ok := v.([]interface{}); ok {
                sslice := make([]string, len(s))
                for i, v := range s {
                    sslice[i] = v.(string)
                }
                JwtValues[k] = strings.Join(sslice, "|")
            } else {
                logger.Log(util.LogDebug, "unknown data type")
            }
    }

Upvotes: 1

William Poussier
William Poussier

Reputation: 1728

Not sure to have fully understood your question, but it seems you're on the right track.

    parts := make([]string, s.Len())
    for i := 0; i < s.Len(); i++ {
        parts = append(parts, s.Index(i).String())
    }
    jwtValues[k] = strings.Join(parts, "|")

Upvotes: 0

Related Questions