展平参数列表,其中参数可以是切片或数组 [英] flatten arguments list, where arguments might be slices or arrays

查看:78
本文介绍了展平参数列表,其中参数可以是切片或数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有这样的功能:

func AcceptsAnything(v ...interface{}){
  args =: FlattenDeep(v);  // flatten any arrays or slices
}

我正在尝试实现FlattenDeep:

I am trying to implement FlattenDeep:

func getKind(v interface{}) string {

    rt := reflect.TypeOf(v)
    switch rt.Kind() {
    case reflect.Slice:
        return "slice"
    case reflect.Array:
        return "array"
    default:
        return "unknown"
    }

}

func FlattenDeep(args ...interface{}) []interface{} {
    list := []interface{}{}

   for _, v := range args {

     kind := getKind(v);

     if kind != "unknown" {
        list = append(list, FlattenDeep(v)...)  // does not compile
     } else{
        list = append(list, v);
       }
    }
   return list;
}

但是我不知道如何一次将多个项目添加到列表中.我应该只遍历FlattenDeep的结果,还是可以分散结果并将其附加到列表中?

but I don't know how to append multiple items to the list at once. Should I just loop over the results of FlattenDeep or is there a way to spread the results and append them to the list?

这可能有效:

func FlattenDeep(args ...interface{}) []interface{} {
    list := []interface{}{}

    for _, v := range args {

        kind := getKind(v);
        if kind != "unknown" {
            for _, z := range FlattenDeep((v.([]interface{})...) {
                list = append(list, z)
            }

        } else {
            list = append(list, v);
        }
    }
    return list;
}

但是我正在寻找一些不太可能的东西

but I am looking for something a little less verbose if possible

推荐答案

以下是将任意切片和数组展平为[] interface {}的方法:

Here's how to flatten arbitrary slices and arrays to a []interface{}:

func flattenDeep(args []interface{}, v reflect.Value) []interface{} {

    if v.Kind() == reflect.Interface {
        v = v.Elem()
    }

    if v.Kind() == reflect.Array || v.Kind() == reflect.Slice {
        for i := 0; i < v.Len(); i++ {
            args = flattenDeep(args, v.Index(i))
        }
    } else {
        args = append(args, v.Interface())
    }

    return args
}

func AcceptsAnything(v ...interface{}) {
    args := flattenDeep(nil, reflect.ValueOf(v))
    fmt.Println(args)
}

在操场上运行

如果函数必须处理具有任意元素类型的切片和数组类型,则应用程序必须使用反射API遍历切片或数组,以将值放入[]接口{}.

If the function must handle slice and array types with an arbitrary element type, then the application must iterate through the slice or array using the reflect API to get the values into an []interface{}.

如果只需要展平[] interface {},则不需要反射API:

If you only need to flatten []interface{}, then the reflect API is not needed:

func flattenDeep(args []interface{}, v interface{}) []interface{} {
    if s, ok := v.([]interface{}); ok {
        for _, v := range s {
            args = flattenDeep(args, v)
        }
    } else {
        args = append(args, v)
    }
    return args
}

func AcceptsAnything(v ...interface{}) {
    args := flattenDeep(nil, v)
    fmt.Println(args)
}

在操场上运行.

这篇关于展平参数列表,其中参数可以是切片或数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆