v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/util/slice/flatten.go (about)

     1  package slice
     2  
     3  import "reflect"
     4  
     5  func Flatten[T any](data any) []T {
     6  TYPE_SWITCH:
     7  	switch v := data.(type) {
     8  	case T:
     9  		return []T{v}
    10  	case *T:
    11  		return []T{*v}
    12  	case []T:
    13  		return v
    14  	case *[]T:
    15  		return *v
    16  	case [][]T:
    17  		var result []T
    18  		for i := range v {
    19  			result = append(result, v[i]...)
    20  		}
    21  		return result
    22  	case *[][]T:
    23  		var result []T
    24  		for i := range *v {
    25  			result = append(result, (*v)[i]...)
    26  		}
    27  		return result
    28  	default:
    29  		rv := reflect.ValueOf(data)
    30  		switch rv.Kind() {
    31  		case reflect.Pointer:
    32  			data = rv.Elem().Interface()
    33  			goto TYPE_SWITCH
    34  		case reflect.Slice:
    35  			var result []T
    36  			for i := 0; i < rv.Len(); i++ {
    37  				elem := rv.Index(i).Interface()
    38  				result = append(result, Flatten[T](elem)...)
    39  			}
    40  			return result
    41  		case reflect.Array:
    42  			var result []T
    43  			for i := 0; i < rv.Len(); i++ {
    44  				elem := rv.Index(i).Interface()
    45  				result = append(result, Flatten[T](elem)...)
    46  			}
    47  			return result
    48  		case reflect.Struct:
    49  			var result []T
    50  			for i := 0; i < rv.NumField(); i++ {
    51  				elem := rv.Field(i).Interface()
    52  				result = append(result, Flatten[T](elem)...)
    53  			}
    54  			return result
    55  		case reflect.Map:
    56  			var result []T
    57  			for _, key := range rv.MapKeys() {
    58  				elem := rv.MapIndex(key).Interface()
    59  				result = append(result, Flatten[T](key.Interface())...)
    60  				result = append(result, Flatten[T](elem)...)
    61  			}
    62  			return result
    63  		}
    64  	}
    65  	return nil
    66  }