dongyu4908 2018-12-21 01:40
浏览 49
已采纳

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

If I have a func like this:

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

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

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?

This might work:

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

  • 写回答

1条回答 默认 最新

  • douhuifen9942 2018-12-21 02:30
    关注

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

    Run it on the Playground

    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{}.

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

    Run it on the Playground.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想用@vueuse 把项目动态改成深色主题,localStorge里面的vueuse-color-scheme一开始就给我改成了dark,不知道什么原因(相关搜索:背景颜色)
  • ¥20 OPENVPN连接问题
  • ¥15 flask实现搜索框访问数据库
  • ¥15 mrk3399刷完安卓11后投屏调试只能显示一个设备
  • ¥100 如何用js写一个游戏云存档
  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计