Skip to content

Commit a742ec8

Browse files
committed
add exslices.Slice function
1 parent 940056f commit a742ec8

File tree

2 files changed

+183
-0
lines changed

2 files changed

+183
-0
lines changed

exslices/exslices.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package exslices
2+
3+
// Slice returns a slice view of arr from start up to, but not including, end.
4+
// Negative indices are resolved from the end, and an omitted end means len(arr).
5+
func Slice[T any](arr []T, start int, end_ ...int) []T {
6+
length := len(arr)
7+
8+
if length == 0 {
9+
return []T{}
10+
}
11+
12+
begin := start
13+
if begin < 0 {
14+
begin = length + begin
15+
if begin < 0 {
16+
begin = 0
17+
}
18+
}
19+
if begin > length {
20+
begin = length
21+
}
22+
23+
end := length
24+
if len(end_) > 0 {
25+
end = end_[0]
26+
if end < 0 {
27+
end = length + end
28+
}
29+
if end < 0 {
30+
end = 0
31+
}
32+
if end > length {
33+
end = length
34+
}
35+
}
36+
37+
if end < begin {
38+
end = begin
39+
}
40+
41+
if end == begin {
42+
return []T{}
43+
}
44+
45+
return arr[begin:end]
46+
}

exslices/exslices_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package exslices
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestSlice(t *testing.T) {
10+
nums := []int{0, 1, 2, 3, 4, 5}
11+
12+
t.Run("only provide start", func(t *testing.T) {
13+
assert.Equal(t,
14+
[]int{0, 1, 2, 3, 4, 5},
15+
Slice(nums, 0),
16+
)
17+
18+
assert.Equal(t,
19+
[]int{2, 3, 4, 5},
20+
Slice(nums, 2),
21+
)
22+
23+
assert.Equal(t,
24+
[]int{5},
25+
Slice(nums, 5),
26+
)
27+
28+
assert.Equal(t,
29+
[]int{},
30+
Slice(nums, 6),
31+
)
32+
33+
assert.Equal(t,
34+
[]int{},
35+
Slice(nums, 999),
36+
)
37+
})
38+
39+
t.Run("provide start and end", func(t *testing.T) {
40+
assert.Equal(t,
41+
[]int{0, 1, 2, 3, 4, 5},
42+
Slice(nums, 0, 6),
43+
)
44+
45+
assert.Equal(t,
46+
[]int{0, 1, 2, 3},
47+
Slice(nums, 0, 4),
48+
)
49+
50+
assert.Equal(t,
51+
[]int{2, 3},
52+
Slice(nums, 2, 4),
53+
)
54+
55+
assert.Equal(t,
56+
[]int{1, 2, 3, 4},
57+
Slice(nums, 1, 5),
58+
)
59+
60+
assert.Equal(t,
61+
[]int{1, 2, 3, 4, 5},
62+
Slice(nums, 1, 999),
63+
)
64+
65+
assert.Equal(t,
66+
[]int{},
67+
Slice(nums, 1, 1),
68+
)
69+
70+
assert.Equal(t,
71+
[]int{},
72+
Slice(nums, 999, 1),
73+
)
74+
})
75+
76+
t.Run("negative start", func(t *testing.T) {
77+
assert.Equal(t,
78+
[]int{4, 5},
79+
Slice(nums, -2),
80+
)
81+
82+
assert.Equal(t,
83+
[]int{0, 1, 2, 3, 4, 5},
84+
Slice(nums, -999),
85+
)
86+
})
87+
88+
t.Run("negative end", func(t *testing.T) {
89+
assert.Equal(t,
90+
[]int{0, 1, 2, 3, 4},
91+
Slice(nums, 0, -1),
92+
)
93+
94+
assert.Equal(t,
95+
[]int{0, 1, 2, 3},
96+
Slice(nums, 0, -2),
97+
)
98+
99+
assert.Equal(t,
100+
[]int{},
101+
Slice(nums, 0, -999),
102+
)
103+
})
104+
105+
t.Run("negative start and end", func(t *testing.T) {
106+
assert.Equal(t,
107+
[]int{1, 2, 3, 4},
108+
Slice(nums, -5, -1),
109+
)
110+
111+
assert.Equal(t,
112+
[]int{3},
113+
Slice(nums, -3, -2),
114+
)
115+
116+
assert.Equal(t,
117+
[]int{},
118+
Slice(nums, -1, -999),
119+
)
120+
121+
assert.Equal(t,
122+
[]int{0, 1, 2, 3, 4},
123+
Slice(nums, -999, -1),
124+
)
125+
})
126+
127+
t.Run("returning result must be a reference", func(t *testing.T) {
128+
nums := []int{0, 1, 2, 3, 4, 5}
129+
130+
view := Slice(nums, 1, -1)
131+
assert.Equal(t, []int{1, 2, 3, 4}, view)
132+
133+
view[1] = 999
134+
assert.Equal(t, []int{1, 999, 3, 4}, view)
135+
assert.Equal(t, []int{0, 1, 999, 3, 4, 5}, nums)
136+
})
137+
}

0 commit comments

Comments
 (0)