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

huangapple go评论82阅读模式
英文:

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

问题

如何将[]interface{}转换为[]string,或者将其作为一个连接的字符串返回,其中包含[]interface{}中的所有元素?下面的屏幕截图显示了类型为[]interface{}且长度为2的scope的确切值。在下面的代码中,caseslice。目前我正在使用反射来实现这一点,但效果不好。想知道是否有更好的方法来连接一个[]interface{}元素的切片或数组。

我还尝试使用json unmarshal,像这样"json.Unmarshal([]byte(jwtResp),&mymap)",但在将jwt.MapClaims转换为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)
// 我们不知道这里处理的是哪种数据类型,所以使用基于值数据类型的switch case
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)) // 这是 []interface{}
		fmt.Println("type is :", reflect.TypeOf(v).Kind()) // 这是 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")
	}
}

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(&quot;tp is : &quot;, reflect.TypeOf(v)) // this is []interface{}
			fmt.Println(&quot;type is : &quot;, reflect.TypeOf(v).Kind()) // this is slice
			s := reflect.ValueOf(v)
			for i := 0; i &lt; s.Len(); i++ {
				jwtValues[k] += s.Index(i).Interface().(string)
				jwtValues[k] += &quot;|&quot;
			}

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

		default:
			fmt.Println(&quot;unknown datatype&quot;)
		}
	}

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

答案1

得分: 1

感谢您的建议。下面是我找到的最接近的解决方案,将 'switch' 替换为 'if' 条件,并添加类型断言。使用下面的代码,我会判断 jwtResp 的值是一个切片、字符串还是其他类型。如果是切片,我会遍历这些值([]interface 类型,其中元素是字符串类型),并将它们连接成一个字符串。

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")
    }
}

希望对您有帮助!

英文:

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, &quot;|&quot;)
			} else {
				logger.Log(util.LogDebug, &quot;unknown data type&quot;)
			}
    }

答案2

得分: 0

我已经翻译好了你提供的代码部分:

不确定是否完全理解了你的问题但看起来你走在正确的轨道上

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

希望对你有帮助!

英文:

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 &lt; s.Len(); i++ {
        parts = append(parts, s.Index(i).String())
    }
    jwtValues[k] = strings.Join(parts, &quot;|&quot;)

huangapple
  • 本文由 发表于 2017年4月27日 21:54:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/43659928.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定