Last active
September 12, 2019 18:43
-
-
Save sjeandeaux/873110282580fce47c003a4c4e0e4035 to your computer and use it in GitHub Desktop.
Flatten an array. You can play with it here => https://play.golang.org/p/Y2PbROlvyNF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"reflect" | |
) | |
//flatten it flattens the array | |
//It returnes the flatten array. | |
func flatten(toFlatten []interface{}) []interface{} { | |
if len(toFlatten) == 0 { | |
return toFlatten | |
} | |
return flattenSub(nil, reflect.ValueOf(toFlatten)) | |
} | |
//flattenSub flatten an array or slice | |
//This function returns the flatten array. | |
//It takes args which is the array of current elements already flatten | |
// v the current element to manage | |
func flattenSub(args []interface{}, v reflect.Value) []interface{} { | |
//if the type v is an interface, it gets the value | |
if v.Kind() == reflect.Interface { | |
v = v.Elem() | |
} | |
//for an array or a slice, it loops on the elements and calls flattenSub. | |
switch v.Kind() { | |
case reflect.Array: | |
fallthrough | |
case reflect.Slice: | |
for i := 0; i < v.Len(); i++ { | |
args = flattenSub(args, v.Index(i)) | |
} | |
default: | |
args = append(args, v.Interface()) | |
} | |
return args | |
} | |
func main() { | |
toFlatten := []interface{}{ | |
[]interface{}{ | |
[]interface{}{ | |
1, | |
2, | |
[]interface{}{3}, | |
}, | |
}, | |
4, | |
} | |
fmt.Println(flatten(toFlatten)) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"reflect" | |
"testing" | |
) | |
func Test_flatten(t *testing.T) { | |
tests := []struct { | |
name string | |
args []interface{} | |
want []interface{} | |
}{ | |
{ | |
name: "nil", | |
args: nil, | |
want: nil, | |
}, | |
{ | |
name: "empty", | |
args: []interface{}{}, | |
want: []interface{}{}, | |
}, | |
{ | |
name: "one element", | |
args: []interface{}{1}, | |
want: []interface{}{1}, | |
}, | |
{ | |
name: "already flat", | |
args: []interface{}{1, 2, 3, 4, 5}, | |
want: []interface{}{1, 2, 3, 4, 5}, | |
}, | |
{ | |
name: "flatten", | |
args: []interface{}{ | |
[]interface{}{ | |
[]interface{}{ | |
1, | |
2, | |
[]interface{}{3}, | |
}, | |
}, | |
4, | |
}, | |
want: []interface{}{1, 2, 3, 4}, | |
}, | |
{ | |
name: "flatten with array", | |
args: []interface{}{[...]int{1, 2, 3, 4}}, | |
want: []interface{}{1, 2, 3, 4}, | |
}, | |
} | |
for _, tt := range tests { | |
t.Run(tt.name, func(t *testing.T) { | |
if got := flatten(tt.args); !reflect.DeepEqual(got, tt.want) { | |
t.Errorf("flatten() = %v, want %v", got, tt.want) | |
} | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment