一尘不染

展平参数列表,其中参数可以是切片或数组

go

如果我有这样的功能:

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

我正在尝试实现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的结果上循环还是有一种方法可以分散结果并将它们附加到列表中?

这可能起作用:

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;
}

但我正在寻找一些不太详细的东西


阅读 146

收藏
2020-07-02

共1个答案

一尘不染

以下是将任意切片和数组展平为[] 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遍历切片或数组,以将值放入[] interface {}。

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

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

在Playground上运行它

2020-07-02