Skip to content

Commit af4262d

Browse files
Implementing Zip function
1 parent 4f3b530 commit af4262d

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

zip.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package funk
2+
3+
import (
4+
"reflect"
5+
)
6+
7+
// Tuple is the return type of Zip
8+
type Tuple struct {
9+
Element1 interface{}
10+
Element2 interface{}
11+
}
12+
13+
// Zip returns a list of tuples, where the i-th tuple contains the i-th element
14+
// from each of the input iterables. The returned list is truncated in length
15+
// to the length of the shortest input iterable.
16+
func Zip(slice1 interface{}, slice2 interface{}) []Tuple {
17+
inValue1 := reflect.ValueOf(slice1)
18+
inValue2 := reflect.ValueOf(slice2)
19+
kind1 := inValue1.Type().Kind()
20+
kind2 := inValue2.Type().Kind()
21+
22+
result := []Tuple{}
23+
for _, kind := range []reflect.Kind{kind1, kind2} {
24+
if kind != reflect.Slice && kind != reflect.Array {
25+
return result
26+
}
27+
}
28+
29+
var minLength int
30+
length1 := inValue1.Len()
31+
length2 := inValue2.Len()
32+
if length1 <= length2 {
33+
minLength = length1
34+
} else {
35+
minLength = length2
36+
}
37+
38+
for i := 0; i < minLength; i++ {
39+
newTuple := Tuple{
40+
Element1: inValue1.Index(i).Interface(),
41+
Element2: inValue2.Index(i).Interface(),
42+
}
43+
result = append(result, newTuple)
44+
}
45+
return result
46+
}

zip_test.go

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package funk
2+
3+
import (
4+
"testing"
5+
"github.com/stretchr/testify/assert"
6+
)
7+
8+
func TestZipEmptyResult(t *testing.T) {
9+
map1 := map[string]int{"a": 1, "b": 2}
10+
array1 := []int{21, 22, 23}
11+
emptySlice := []int{}
12+
13+
t.Run("NonSliceOrArray", func(t *testing.T) {
14+
expected := []Tuple{}
15+
result := Zip(map1, array1)
16+
assert.Equal(t, result, expected)
17+
})
18+
19+
t.Run("ZerosSized", func(t *testing.T) {
20+
expected := []Tuple{}
21+
result := Zip(emptySlice, array1)
22+
assert.Equal(t, result, expected)
23+
})
24+
}
25+
26+
func zipIntsAndAssert(t *testing.T, data1, data2 interface{}) {
27+
t.Run("FirstOneShorter", func(t *testing.T) {
28+
expected := []Tuple{
29+
{Element1: 11, Element2: 21},
30+
{Element1: 12, Element2: 22},
31+
{Element1: 13, Element2: 23},
32+
}
33+
result := Zip(data1, data2)
34+
assert.Equal(t, result, expected)
35+
})
36+
37+
t.Run("SecondOneShorter", func(t *testing.T) {
38+
expected := []Tuple{
39+
{Element1: 21, Element2: 11},
40+
{Element1: 22, Element2: 12},
41+
{Element1: 23, Element2: 13},
42+
}
43+
result := Zip(data2, data1)
44+
assert.Equal(t, result, expected)
45+
})
46+
}
47+
48+
func TestZipSlices(t *testing.T) {
49+
slice1 := []int{11, 12, 13}
50+
slice2 := []int{21, 22, 23, 24, 25}
51+
zipIntsAndAssert(t, slice1, slice2)
52+
}
53+
54+
func TestZipArrays(t *testing.T) {
55+
array1 := [...]int{11, 12, 13}
56+
array2 := [...]int{21, 22, 23, 24, 25}
57+
zipIntsAndAssert(t, array1, array2)
58+
}
59+
60+
func TestZipStructs(t *testing.T) {
61+
type struct1 struct {
62+
Member1 uint16
63+
Member2 string
64+
}
65+
type struct2 struct {
66+
Member3 bool
67+
}
68+
type struct3 struct {
69+
Member4 int
70+
Member5 struct2
71+
}
72+
73+
slice1 := []struct1{
74+
{
75+
Member1: 11,
76+
Member2: "a",
77+
},
78+
{
79+
Member1: 12,
80+
Member2: "b",
81+
},
82+
{
83+
Member1: 13,
84+
Member2: "c",
85+
},
86+
}
87+
slice2 := []struct3{
88+
{
89+
Member4: 21,
90+
Member5: struct2{
91+
Member3: false,
92+
},
93+
},
94+
{
95+
Member4: 22,
96+
Member5: struct2{
97+
Member3: true,
98+
},
99+
},
100+
}
101+
102+
expected := []Tuple{
103+
{
104+
Element1: struct1{
105+
Member1: 11,
106+
Member2: "a",
107+
},
108+
Element2: struct3{
109+
Member4: 21,
110+
Member5: struct2{
111+
Member3: false,
112+
},
113+
},
114+
},
115+
{
116+
Element1: struct1{
117+
Member1: 12,
118+
Member2: "b",
119+
},
120+
Element2: struct3{
121+
Member4: 22,
122+
Member5: struct2{
123+
Member3: true,
124+
},
125+
},
126+
},
127+
}
128+
129+
result := Zip(slice1, slice2)
130+
assert.Equal(t, expected, result)
131+
}

0 commit comments

Comments
 (0)