-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathslice.go
More file actions
286 lines (235 loc) · 5.33 KB
/
slice.go
File metadata and controls
286 lines (235 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
package oper
import "github.com/spf13/cast"
type Number interface {
~int8 | ~int16 | ~int | ~int32 | ~int64 |
~uint8 | ~uint16 | ~uint | ~uint32 | ~uint64
}
type List interface {
Number | ~string
}
func In[N List](fat []N, sub N) bool {
_, ok := InI(fat, sub)
return ok
}
func Index[N List](fat []N, idx N) int {
index, _ := InI(fat, idx)
return index
}
func Extend[N List](fat []N, sub []N) []N {
fat = append(fat, sub...)
return fat
}
func Pop[N List](fat []N, idx int) []N {
if idx >= len(fat) || len(fat)+idx < 0 {
return nil
}
if idx < 0 {
idx = len(fat) + idx
}
return append(fat[:idx], fat[(idx+1):]...)
}
func Remove[N List](fat []N, value N) []N {
for i, v := range fat {
if v == value {
fat = append(fat[:i], fat[(i+1):]...)
}
}
return fat
}
func Append[N List](fat []N, value N) []N {
return append(fat, value)
}
func Insert[N List](fat []N, idx int, value N) []N {
// 检查索引是否有效
if idx < 0 {
idx = len(fat) + idx + 1 // 负数索引从末尾开始计算
if idx < 0 {
idx = 0 // 如果计算后的索引仍小于0,则插入到开头
}
}
if idx > len(fat) {
idx = len(fat) // 如果索引超过长度,则插入到末尾
}
// 分配足够容量避免多次分配
result := make([]N, len(fat)+1)
// 复制前面部分
copy(result, fat[:idx])
// 插入新值
result[idx] = value
// 复制后面部分
copy(result[idx+1:], fat[idx:])
return result
}
func Count[N List](fat []N, value N) (count int) {
for _, v := range fat {
if v == value {
count += 1
}
}
return count
}
func InI[N List](fat []N, sub N) (int, bool) {
for i, v := range fat {
if v == sub {
return i, true
}
}
return -1, false
}
func Equal[N List](fat []N, sub []N) bool {
if len(fat) != len(sub) {
return false
}
for i, n := range fat {
if n != sub[i] {
return false
}
}
return true
}
// Map 对切片中的每个元素应用函数并返回新切片 - 类似Python和JavaScript的map
func Map[T, R List](slice []T, fn func(T) R) []R {
result := make([]R, len(slice))
for i, v := range slice {
result[i] = fn(v)
}
return result
}
// Filter 过滤满足条件的元素 - 类似Python和JavaScript的filter
func Filter[T List](slice []T, fn func(T) bool) []T {
var result []T
for _, v := range slice {
if fn(v) {
result = append(result, v)
}
}
return result
}
// Any 检查是否有任一元素满足条件 - 类似Python的any
func Any[T List](slice []T, fn func(T) bool) bool {
for _, v := range slice {
if fn(v) {
return true
}
}
return false
}
// All 检查是否所有元素都满足条件 - 类似Python的all
func All[T List](slice []T, fn func(T) bool) bool {
for _, v := range slice {
if !fn(v) {
return false
}
}
return true
}
// Find 查找满足条件的第一个元素及其索引 - 类似JavaScript的find
func Find[T List](slice []T, fn func(T) bool) (T, int) {
var zero T
for i, v := range slice {
if fn(v) {
return v, i
}
}
return zero, -1
}
// FindIndex 查找满足条件的第一个元素的索引 - 类似JavaScript的findIndex
func FindIndex[T List](slice []T, fn func(T) bool) int {
for i, v := range slice {
if fn(v) {
return i
}
}
return -1
}
// Some 检查是否有任一元素满足条件 - 类似JavaScript的some
func Some[T List](slice []T, fn func(T) bool) bool {
return Any(slice, fn)
}
// Every 检查是否所有元素都满足条件 - 类似JavaScript的every
func Every[T List](slice []T, fn func(T) bool) bool {
return All(slice, fn)
}
// Chunk 将切片分块 - 类似Lodash的chunk
func Chunk[T List](slice []T, size int) [][]T {
if size <= 0 {
return [][]T{}
}
var chunks [][]T
for size < len(slice) {
slice, chunks = slice[size:], append(chunks, slice[0:size:size])
}
if len(slice) > 0 {
chunks = append(chunks, slice)
}
return chunks
}
// Flatten 将二维切片扁平化为一维 - 类似Lodash的flatten
func Flatten[T List](slice [][]T) []T {
var result []T
for _, s := range slice {
result = append(result, s...)
}
return result
}
// UniqBy 基于提供的比较函数去重 - 类似Lodash的uniqBy
func UniqBy[T List](slice []T, fn func(T) T) []T {
var result []T
seen := make(map[string]bool)
for _, v := range slice {
key := fn(v) // 应用函数获得比较键
keyStr := cast.ToString(key)
if !seen[keyStr] {
seen[keyStr] = true
result = append(result, v)
}
}
return result
}
// GroupBy 按照指定条件分组 - 类似Lodash的groupBy
func GroupBy[T List, K comparable](slice []T, fn func(T) K) map[K][]T {
result := make(map[K][]T)
for _, v := range slice {
key := fn(v)
result[key] = append(result[key], v)
}
return result
}
// Contains 检查切片是否包含指定元素 - 类似各种语言的includes方法
func Contains[T List](slice []T, element T) bool {
for _, v := range slice {
if v == element {
return true
}
}
return false
}
// Reverse 反转切片元素的顺序
func Reverse[T List](slice []T) []T {
length := len(slice)
result := make([]T, length)
for i, v := range slice {
result[length-i-1] = v
}
return result
}
// Take 获取切片的前n个元素
func Take[T List](slice []T, n int) []T {
if n > len(slice) {
n = len(slice)
}
if n < 0 {
n = 0
}
return slice[:n]
}
// Drop 丢弃切片的前n个元素
func Drop[T List](slice []T, n int) []T {
if n > len(slice) {
return []T{}
}
if n < 0 {
n = 0
}
return slice[n:]
}