Last active
August 31, 2018 11:07
-
-
Save thesyncim/06137668e7c3fe7f8b3091a7441eda03 to your computer and use it in GitHub Desktop.
flatten slice
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 flatten | |
import ( | |
"reflect" | |
) | |
//flatten method creates a new slice with all sub-slice elements concatted into it recursively | |
func Flatten(slice interface{}) []interface{} { | |
//validate input | |
//must be a slice | |
if reflect.TypeOf(slice).Kind() != reflect.Slice { | |
// this should be avoided and the function should return an error on invalid input | |
// keep it as it is just to match the exercise function signature | |
panic("must be a slice") | |
} | |
return doFlatten(slice) | |
} | |
//doFlatten do the actual work | |
//this could be simplified if we restrict to int or int64 | |
func doFlatten(slice interface{}) []interface{} { | |
var result []interface{} | |
switch v := slice.(type) { | |
case []interface{}: | |
for i := range v { | |
result = append(result, doFlatten(v[i])...) | |
} | |
case int, uint, uint64, int64, uint32, int32, uint16, int16, uint8, int8: | |
result = append(result, v) | |
case []int: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []uint: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []uint64: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []int64: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []uint32: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []int32: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []uint16: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []int16: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []uint8: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
case []int8: | |
for i := range v { | |
result = append(result, v[i]) | |
} | |
} | |
return result | |
} |
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 flatten | |
import ( | |
"reflect" | |
"testing" | |
) | |
func TestFlatten(t *testing.T) { | |
type args struct { | |
slice interface{} | |
} | |
tests := []struct { | |
name string | |
args args | |
want []interface{} | |
}{ | |
{ | |
name: "interface", | |
args: args{ | |
slice: []interface{}{ | |
[]interface{}{ | |
1, 2, []interface{}{ | |
3, | |
}, | |
}, | |
4, | |
}, | |
}, | |
want: []interface{}{1, 2, 3, 4}, | |
}, | |
{ | |
name: "mixed unsigned /signed 2", | |
args: args{ | |
slice: []interface{}{ | |
[]interface{}{ | |
1, 2, []int{ | |
3, | |
}, | |
}, | |
uint(4), | |
}, | |
}, | |
want: []interface{}{1, 2, 3, uint(4)}, | |
}, | |
{ | |
name: "mixed unsigned /signed", | |
args: args{ | |
slice: []interface{}{ | |
[]interface{}{ | |
uint8(1), int16(2), []int{ | |
3, | |
}, | |
}, | |
uint(4), | |
}, | |
}, | |
want: []interface{}{uint8(1), int16(2), 3, uint(4)}, | |
}, | |
{ | |
name: "recursive 4 levels", | |
args: args{ | |
slice: []interface{}{ | |
1, | |
[]interface{}{ | |
2, []interface{}{ | |
3, []interface{}{ | |
4, | |
}, | |
}, | |
}, | |
}, | |
}, | |
want: []interface{}{1, 2, 3, 4}, | |
}, | |
{ | |
name: "nothing to do", | |
args: args{ | |
slice: []interface{}{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.slice); !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