mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-04 12:52:28 +08:00
refactor: refact some sliceutil functions
This commit is contained in:
@@ -1,51 +1,51 @@
|
|||||||
-----BEGIN rsa private key-----
|
-----BEGIN rsa private key-----
|
||||||
MIIJKQIBAAKCAgEAwUdYQvqsym2r86Xlcu8CzK6MAjtZH3aW/BsfZ852dra1nYGq
|
MIIJKQIBAAKCAgEAoJVrCBR3dJsdj0Gg9tlkToGvywJnJqVWBPgjnS+Hn5Ksxk1y
|
||||||
UoJMe31eiurN9BK/OXmo7D3zm3OCCl/uGUCiNgWKYAfaW2o4rFE7tHwHf5E4/bLm
|
zBieL0aQ84hVXYt0yhCgiDl/eDmgdawqUZ5j2PhFBDahjvBnchY2ViZXNE61ya3Y
|
||||||
p2c6+xwP5bSo6r0pXonszPpMK4sTHNxgaXLhHYdx1dKXWt5SvHXo012fWsXTC7MQ
|
PEPIwUsZ1Wsmzu5cX6gA1HqE2nx8iZlJQcbG/rdoxyebhdvUj6iGGvgskggkVYvD
|
||||||
rpTeQIOZViC3ldQpXO026nKzwzgr7WW9kZakHYPz0IdwQGkl6/EY3LpnP3ADsop9
|
Yuct+iRekfHMxG3ON+wJ31AC2+0B6w6vgvt11uZpAnG/lR2APzTxnDHVHEXGmTti
|
||||||
HWZmTIcZUfaztdwnC9JS4zJg1gGMioQXgavlPOVEDmXk8Oi+1ORB6CphlovSeuT9
|
clb3ko4zRvTREsY4zSFSq0Io5K29ooYw/pHvhw3hvirRzjYkaxK5yzLCw788FkRL
|
||||||
IxIoSlv77ARazKZcTfnxzXgpPT2wBdiGiTvq2/vON1IvjDPd4MkBYEx3k5tbdL//
|
jpO4yuTYxD3pQ6HpfMMpTl9nCK3IOMqbyaX2espY0zmJr/vqbWgqzSlyptXDW80/
|
||||||
HjzkKlg/zElELvrXEQFpdvzCdrqrTDQ56ej1A5AH1q6eIJULh5hhq5jLIxkSYiiC
|
mAn1nDhQe1qkTW94gqL9GKhGtydFCOKxfIM7Y5X7DlMXc1kbup5pw3p8xkltD4KN
|
||||||
rXYlTSPX7D9t7PLHj5AVv2PkHhuU1pwv7HnLsPfTwxYcxjygLP8lJPPE+y8UJLFC
|
cG+QuePPIvFp05oiLAHZpO0d3i2pAtiVyQ+7YvlEQlqw0LCz8MaDRGZg4+Q3nxPt
|
||||||
OUKkPr9dGLqA8G6ZvWhYHTyiwVEENwb+RdV2lakg7YNgRfEymvY3HqiiZiH8T7eO
|
mg4z7Ms8gsZaKFiyRZCMOg6NEDFwhZPAFJ+6JH6Pnbq244LkKYCJNuZpp9rYeOWI
|
||||||
c1tt/eF3gDbG2jjlD83cxYetYFNgtSk/+0gydBQKRR+w8PUTdLb1ZZhzk/7yZCrr
|
IMNevQyHc6iorInnSGJfzxz347NfwV2fcn4bgQGPbHJOMNDlHnVZgp2ONlVvaSC6
|
||||||
sh043967ECjNI5hyvSYdR+sj3W9i39Jj/4JSX05C9FKEAehvubw9V/AMXcMCAwEA
|
DWWE1iGNmOcNcc09PJV87qf8x9SI5FXipsvnfiVynueMcgSwqQRddt4O408CAwEA
|
||||||
AQKCAgEAk0BRxCXLQyYvHR/FIb1qupo43PJuQgRNn6DiWmn34xXsZCWHp/jRYDvx
|
AQKCAgADGN6nmT10kklPqgRgvnCg0v+A+tric+3kyqRlM7V57mpGqNe99/uVDddd
|
||||||
rZCafFtUCOvhgKrqUAK+jjzr351YeCPcerFA8OiKaO4yuJzN8aiobNDB3cROMUX9
|
2xNKapYmD4wJFJLQzsu5eUiXqmZimOc73ZHgH+Le4G7L2pF0ANCgwymYf/YvRDOL
|
||||||
7pmnH8AiJn6aRMhlA7+fPhu/8Favn5mzZp5c5cP/8Mk8KtxnLfcNhRpVmUydzzTz
|
WjW1aAOAFM1vS62kSSJdxQcUrbDI2OC8dpcZTdQbsTRk8MRrTJzmyXtLPQo1+N2a
|
||||||
u6SNeb78DGpFrnTY8+B1xxX+SU8llb8UIEkvgkMZuxoiQPha9P/YMUxFagK76Y38
|
Ev/QCg4gJf1KwVBMzZVr4yyfahoruuXrliYLyjXfAjZmvM9PbEkYS3zql6LOwM9c
|
||||||
AnAcFm+159HDiIi3MhRYCKf+aLKXob9iDD4hIFGSIgwNEl5HnzTDlRGksfWBcLWH
|
XvxpUEloK2xcwTnorzEpIU1wm3/zKuFfuZOyVnj9V68drCz1eYq/IzIR3eeCgkds
|
||||||
xxbCPqx4IohMaqgjcx7uXmXKif92O/QlDw2JGSZX87jdcJTkqc420yGxSOd4xW0j
|
AYWuOEE4lssFJ/HkyPVDoyS+DuViERH05WpaXRZYXKIDbBSkh38JTXMBauyF1yEO
|
||||||
vw1f4dRzQ9pr9S8k9RyXgNLT4a1eXYCjLNRZ9/NZqC16FgbG9kl4/AaBqSEhKURa
|
D5Z8yK5o32n9zArUu9CeW93RIqVx4j8WYdoiEwoDT7AMLr9W5Sl8HsOC0NVBBT4A
|
||||||
ZG2uk8zBmej8FJeHUV8KFSnuaaiHwY5weN+afyWt2oqvydM444B0XG/IdAdgYUDY
|
ALilbuYDG2HAcrk9KpYvzHIW6U6yop/0EObljxFQRs0MB4uZUfY3IlHIjOdBeZTV
|
||||||
0CHs9wFcLYs+MfJWk3D+U0/zmcNfLC1e7qJOTheJIWJ2oCLDP3s7+7Bo+7anLRCK
|
uQt8D8DESJf6NF39V21TMuuNxELVDKSyEIEN4AjdrLJKfWg5BgKJvHfzhpqx5rGN
|
||||||
1vXVOmTeWgJ2cLSPi7y9UKjjvm7/Fi3zZclTodZjEKxsDpQ+aE9ihqxjsWjYvJ7E
|
ldEy573GRwG9xrJTAhuMfv7XVWxVqfT2moabFSL2X/PAiwyatgePn4YogHU52iZM
|
||||||
EeUhu9UhMfYbjVRavxWO0CKnJA+ZPLM1y57iarQkBslvHkBM6gECggEBANmzuYwP
|
ExsyY4W0uSX2tKS1gzPLMZNDO+x8GZg/IQ0/agaHVpdmBoQgAQKCAQEAxOMIrpbf
|
||||||
PoWw61sbsRmXsOmGoJJ0RGbB5i3xH0E2Us/+dLMseUi+Z17jccFa9cpYBQEh0PYJ
|
4YCi1O0cXfr9RnsipXBqbmzL9i6S7htIlLP7eGx5V/l+Xz0cOEel3/3/ArBlTY0D
|
||||||
bmU8r69yqjzOLmvCVJb5wRiXof4yGmsXwSWQD/wA0gTka/+iFSiUZtS+0t0qUxce
|
IKFOe0bpxbtI4kuj/NiPFIv8UnrAINyfIIEaNfVzOtjJq0Vj9lPjJsQ6xgvdDY3t
|
||||||
UXM1KQF8tJNPgvivY5jhbaoUgb6TNe0/vX3bRXSnIf3CqRBdpO3jZKwXU8VOFwjZ
|
0NAVXlITSMpFox0dEJ1hMjsvIlI0BY81b0xUHfkw7/POgCamf40YyFWErSsXTCOP
|
||||||
nwoIv0Fki+FWAHHINz8gMmaCDypgzQOOqFd8g7uQLD1tGZhroo479r1+bQU6KBPD
|
H/Ww/w4zaenfvdpHyhqNh4NNfAjPVBk2rka7Nmjo0vVyHs1praQQbIRpicukFdAp
|
||||||
T/9CZwk9g7KVo9boYWH9UaQfi56mUxY1N3MexySecNdORWuqNWut0/H3M88lhM34
|
poGNkBnku02DuJhmCSZ+x6kpY0sg6QWDfTUJr7OYiw2aGB4ztqEYgOa1ToraVZpt
|
||||||
qe0Wiw9F2B/nSIECggEBAONHtPW3Q7nr5PzD44umf6IRMxbt7Op667tuZELECwHv
|
9LwieEnxrNm0TwKCAQEA0MwTlNJz3LM4JjP1O0BzQMmuhogd0wpHatzOXqbrGU+O
|
||||||
lspWYgFyHmIqfjLmj0rXD3ElrIKzSyJLdO3VdtlssSj75ehB7yvMOnRFBld0MtGr
|
Foq0xnPzYn3DQEBRrt6ALqOll0JaHBspXMjz38oRjfCNf0zdPDg2lMS9zszExRVS
|
||||||
laHveGGSt9RLKu2GEnFEzf5ZdP/zay10U0426Q4c26RfS1095pN2hQSst7BNDvoJ
|
UwI0B800I7xAYEE32t4OAhaispy3ij65W8WukLObggH7bHGqiv+M4fdpG0hLXrLl
|
||||||
5RzNaSDo0oPOwYXmJzGh3zrgnAB+jIozlbuR4sP/60JSEHhTHr1jxC57CprRfG3e
|
1Iv85dm4foVJ90mHOHyppUrc31yRvEzozATmYgaUn4Man/Jv4Xu9DizDPh+EP/H3
|
||||||
ZV4Lu+dTde3847tYeeDsoCZrrwN97A2CgoeUHs6oAfLi8QUHsiVu0okG5uy8fApv
|
I9wBvqW+dHV19PoZ6fYPtmws66PHN781ki9QWrqrmSOjrrWTwfbAUA1cKezk2bv/
|
||||||
j2JCEMI60+Nej+q9elWFLjOO79O3zwWUFr6n8pUyZEMCggEARYdsFDpuKn6lvHRs
|
SBPlyZwb7mFLFDoZzK4llTcDfzx0AcofbyrjltkhAQKCAQEAtOU79t1ced4svaHV
|
||||||
rJLQ8tSHhh7SFcuJu1SOOeKiskE/flYO6le9ZgXYN/vYEmboOkNVnK7IblbieXNy
|
bGvNBVLhdEujHi4L//auvOKIf0gWhoBzxObQu0R0hykdOH4wLRJRIT2sX/CVISL4
|
||||||
wXbMRqhLIejkbflHyIqx+1Ab5OZM5JxSdzOI9p0KiupSqVHEwNQas4CAXP42eX4d
|
ato2juScmRWH8ILlpApwOEE8WysDIAySgMDqGdi5jXtpuxaUQZ5ozalXlYF6AJ08
|
||||||
ogq79rb1ZUdiIfbotTgI+hvoZkDYvvf+GDDKlCqEWWHNrlTI8XQOUUpHzAmdI8J8
|
Zqah8MoxCDDxOquyFMCeV3VKzSW+K4Pm+LBzTL82Pv8ug/I+4rQyxZvuRpkAtHch
|
||||||
FlzESZK7alLbJfgV5eACukcepspivE3Ag2HL0e1WfnzSQhUVtpyrXhx7+Td49u+J
|
ufBNyCujxgc7fgSfzpRxmX1JBjqqi8U8FYe6AJ8Ot6GEDZBjP13BNuF5QyjJHlsM
|
||||||
l0jJigKvz377SyK0EdhnIumeKwtCaQSdX3ZlH4y+AQUEcvwTtO3zq2DmzIztntQc
|
EyOXIKW1KjcaSOwdwMMoS7DrLMDsU2iZgTlQGVS2gtfkoZpXfwCIthobaL7qlMar
|
||||||
wZu5gQKCAQEAgZESb3WvbWE2ZIaDxMwBPPITLwIqKq4yjuJq08kRAWSFkQnXyz00
|
q/qidQKCAQAvHEyywIVZ36oknIaRdupKTPcu7ZllG6Wfi/CYVKspC9Uwat19BX59
|
||||||
ZwAUe44GqEKb8gPpKYVu0rkzipZDr8WP5W5c7aAQ6eX+eOQUrmx2wCLSJcPv26gZ
|
04hxf9GuVg+v9kaPiW4Rd2NuxvyXmt05HHSgq3QjeT9/c6Cr/3HKUhRAHHgm5nsE
|
||||||
ljPX4BqrjtkLmfGDippJQltrVk5lY/89k6Ijw58TQIOzZyvTd/UmEZLsgxPy16kC
|
MR6JWU3D+WRJvle5WzjiXWKvPTw09AF7ZP0Yq9DiCeT8uzkg6b/vvweyXF+UcPp6
|
||||||
wdNvbZb8RwYhzV3YcUuzcOHhfVG4dcYCZweDjiTMhGlIoLrSG9pK1hOPtCJ6V3Cz
|
uZJF1HZJHX+dhvWtBBLx3JyOI/DjXz67evZP7oCl7KhsgVcQNkY9s1ei5KoUHQuK
|
||||||
7R1a8iWJLZmX3u9KkXIKzNTW9tWRDnymx8FqZ1Sw0TgxW56MrO7yw7w/gGNrTF7f
|
9VHHE4MzUcybyW6dQFfb0S3CLSDBR+sd43e0HM4Y7pbXuRv5bbT5F7zyw2KOicWX
|
||||||
BmKVJtwnznMjGI9m10qVAXgf00bJOxbEIwKCAQBjylF+1MU629WE+1CIfLtc8v5W
|
lKY/Cxj1ILnkIASO+dHm8XcEOzYcvCMBAoIBAQCzkO/HHbk4RWZuGaeZy9GnwIFV
|
||||||
FRjDYq1lfdbZxqXOKtDkk0cpeRNLNBqdltfl37whi/kTA1ZsYdY+tf2xAewvLlGQ
|
Rhkyo+mxlLRQFqmO3BBl/u5xIfGfTH1ACHlKeK1wBWg8w4MGKFeRHEXQgMJBT9ss
|
||||||
v0YRslw7/KeZQJiCgG7S3CSoV16EJBNsc/wsQukaoM943kgLHGjb6Prie40TPWSZ
|
l3HtVA47Fq4cF/4aaJaWAWOCOjfy/ncwCD8ZLku5OaT1CtWFD67wVKHUcFbImDXz
|
||||||
x5XJk3bJLNF/24qXbeFpPdHptZympiE8/jrSUUMmum8IZeeRXghsi3S/gwFwlXb0
|
VVTRD1XOcuvB4XhSUi/3sPWnOmv0f7VCSUADqXMSjxvlM8mq6POL/MnBmEbaoqXw
|
||||||
mrSuZGmcb7za9pK050CYbSQ2/HoVpBGe9E6B1Ad0jSFfbVCd5vZz+4f4/tB/AEY9
|
Y6uR1LE27TjcSSsUTp4/ryUM1jg4M/4VUt5cWND2CdDEp/itfzfZFOxR5e7hboUM
|
||||||
7XwzpkGrEyWiys2o0XhRv8rMlTDJfU3E8aVwJwEGJOMA5aU1ZJcFAcvIsGlv
|
bqqccVto5QXLIOJ9Vuk/yAVC7WGdIaDbc+XXcQ5ish6KxmesUIIgfdcvFn60
|
||||||
-----END rsa private key-----
|
-----END rsa private key-----
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
-----BEGIN rsa public key-----
|
-----BEGIN rsa public key-----
|
||||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwUdYQvqsym2r86Xlcu8C
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoJVrCBR3dJsdj0Gg9tlk
|
||||||
zK6MAjtZH3aW/BsfZ852dra1nYGqUoJMe31eiurN9BK/OXmo7D3zm3OCCl/uGUCi
|
ToGvywJnJqVWBPgjnS+Hn5Ksxk1yzBieL0aQ84hVXYt0yhCgiDl/eDmgdawqUZ5j
|
||||||
NgWKYAfaW2o4rFE7tHwHf5E4/bLmp2c6+xwP5bSo6r0pXonszPpMK4sTHNxgaXLh
|
2PhFBDahjvBnchY2ViZXNE61ya3YPEPIwUsZ1Wsmzu5cX6gA1HqE2nx8iZlJQcbG
|
||||||
HYdx1dKXWt5SvHXo012fWsXTC7MQrpTeQIOZViC3ldQpXO026nKzwzgr7WW9kZak
|
/rdoxyebhdvUj6iGGvgskggkVYvDYuct+iRekfHMxG3ON+wJ31AC2+0B6w6vgvt1
|
||||||
HYPz0IdwQGkl6/EY3LpnP3ADsop9HWZmTIcZUfaztdwnC9JS4zJg1gGMioQXgavl
|
1uZpAnG/lR2APzTxnDHVHEXGmTticlb3ko4zRvTREsY4zSFSq0Io5K29ooYw/pHv
|
||||||
POVEDmXk8Oi+1ORB6CphlovSeuT9IxIoSlv77ARazKZcTfnxzXgpPT2wBdiGiTvq
|
hw3hvirRzjYkaxK5yzLCw788FkRLjpO4yuTYxD3pQ6HpfMMpTl9nCK3IOMqbyaX2
|
||||||
2/vON1IvjDPd4MkBYEx3k5tbdL//HjzkKlg/zElELvrXEQFpdvzCdrqrTDQ56ej1
|
espY0zmJr/vqbWgqzSlyptXDW80/mAn1nDhQe1qkTW94gqL9GKhGtydFCOKxfIM7
|
||||||
A5AH1q6eIJULh5hhq5jLIxkSYiiCrXYlTSPX7D9t7PLHj5AVv2PkHhuU1pwv7HnL
|
Y5X7DlMXc1kbup5pw3p8xkltD4KNcG+QuePPIvFp05oiLAHZpO0d3i2pAtiVyQ+7
|
||||||
sPfTwxYcxjygLP8lJPPE+y8UJLFCOUKkPr9dGLqA8G6ZvWhYHTyiwVEENwb+RdV2
|
YvlEQlqw0LCz8MaDRGZg4+Q3nxPtmg4z7Ms8gsZaKFiyRZCMOg6NEDFwhZPAFJ+6
|
||||||
lakg7YNgRfEymvY3HqiiZiH8T7eOc1tt/eF3gDbG2jjlD83cxYetYFNgtSk/+0gy
|
JH6Pnbq244LkKYCJNuZpp9rYeOWIIMNevQyHc6iorInnSGJfzxz347NfwV2fcn4b
|
||||||
dBQKRR+w8PUTdLb1ZZhzk/7yZCrrsh043967ECjNI5hyvSYdR+sj3W9i39Jj/4JS
|
gQGPbHJOMNDlHnVZgp2ONlVvaSC6DWWE1iGNmOcNcc09PJV87qf8x9SI5FXipsvn
|
||||||
X05C9FKEAehvubw9V/AMXcMCAwEAAQ==
|
fiVynueMcgSwqQRddt4O408CAwEAAQ==
|
||||||
-----END rsa public key-----
|
-----END rsa public key-----
|
||||||
|
|||||||
200
slice/slice.go
200
slice/slice.go
@@ -59,16 +59,18 @@ func ContainSubSlice[T comparable](slice, subSlice []T) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
elementMap := make(map[T]struct{}, len(slice))
|
elementCount := make(map[T]int, len(slice))
|
||||||
for _, item := range slice {
|
for _, item := range slice {
|
||||||
elementMap[item] = struct{}{}
|
elementCount[item]++
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range subSlice {
|
for _, item := range subSlice {
|
||||||
if _, ok := elementMap[item]; !ok {
|
if elementCount[item] == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
elementCount[item]--
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +83,18 @@ func Chunk[T any](slice []T, size int) [][]T {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range slice {
|
currentChunk := []T{}
|
||||||
l := len(result)
|
|
||||||
if l == 0 || len(result[l-1]) == size {
|
|
||||||
result = append(result, []T{})
|
|
||||||
l++
|
|
||||||
}
|
|
||||||
|
|
||||||
result[l-1] = append(result[l-1], item)
|
for _, item := range slice {
|
||||||
|
if len(currentChunk) == size {
|
||||||
|
result = append(result, currentChunk)
|
||||||
|
currentChunk = []T{}
|
||||||
|
}
|
||||||
|
currentChunk = append(currentChunk, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(currentChunk) > 0 {
|
||||||
|
result = append(result, currentChunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -106,6 +112,7 @@ func Compact[T comparable](slice []T) []T {
|
|||||||
result = append(result, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result[:len(result):len(result)]
|
return result[:len(result):len(result)]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,8 +140,17 @@ func Concat[T any](slices ...[]T) []T {
|
|||||||
func Difference[T comparable](slice, comparedSlice []T) []T {
|
func Difference[T comparable](slice, comparedSlice []T) []T {
|
||||||
result := []T{}
|
result := []T{}
|
||||||
|
|
||||||
|
if len(slice) == 0 {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
comparedMap := make(map[T]struct{}, len(comparedSlice))
|
||||||
|
for _, v := range comparedSlice {
|
||||||
|
comparedMap[v] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if !Contain(comparedSlice, v) {
|
if _, found := comparedMap[v]; !found {
|
||||||
result = append(result, v)
|
result = append(result, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,13 +163,17 @@ func Difference[T comparable](slice, comparedSlice []T) []T {
|
|||||||
// like lodash.js differenceBy: https://lodash.com/docs/4.17.15#differenceBy.
|
// like lodash.js differenceBy: https://lodash.com/docs/4.17.15#differenceBy.
|
||||||
// Play: https://go.dev/play/p/DiivgwM5OnC
|
// Play: https://go.dev/play/p/DiivgwM5OnC
|
||||||
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T {
|
func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(index int, item T) T) []T {
|
||||||
orginSliceAfterMap := Map(slice, iteratee)
|
|
||||||
comparedSliceAfterMap := Map(comparedSlice, iteratee)
|
|
||||||
|
|
||||||
result := make([]T, 0)
|
result := make([]T, 0)
|
||||||
for i, v := range orginSliceAfterMap {
|
|
||||||
if !Contain(comparedSliceAfterMap, v) {
|
comparedMap := make(map[T]struct{}, len(comparedSlice))
|
||||||
result = append(result, slice[i])
|
for _, item := range comparedSlice {
|
||||||
|
comparedMap[iteratee(0, item)] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, item := range slice {
|
||||||
|
transformedItem := iteratee(i, item)
|
||||||
|
if _, found := comparedMap[transformedItem]; !found {
|
||||||
|
result = append(result, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,23 +185,32 @@ func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(inde
|
|||||||
// The comparator is invoked with two arguments: (arrVal, othVal).
|
// The comparator is invoked with two arguments: (arrVal, othVal).
|
||||||
// Play: https://go.dev/play/p/v2U2deugKuV
|
// Play: https://go.dev/play/p/v2U2deugKuV
|
||||||
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(item1, item2 T) bool) []T {
|
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(item1, item2 T) bool) []T {
|
||||||
result := make([]T, 0)
|
|
||||||
|
|
||||||
getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int {
|
getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int {
|
||||||
index := -1
|
|
||||||
for i, v := range arr {
|
for i, v := range arr {
|
||||||
if comparison(item, v) {
|
if comparison(item, v) {
|
||||||
index = i
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]T, 0, len(slice))
|
||||||
|
|
||||||
|
comparedMap := make(map[int]T, len(comparedSlice))
|
||||||
|
for _, v := range comparedSlice {
|
||||||
|
comparedMap[getIndex(comparedSlice, v, comparator)] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range slice {
|
||||||
|
found := false
|
||||||
|
for _, existing := range comparedSlice {
|
||||||
|
if comparator(v, existing) {
|
||||||
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return index
|
if !found {
|
||||||
}
|
result = append(result, v)
|
||||||
|
|
||||||
for i, v := range slice {
|
|
||||||
index := getIndex(comparedSlice, v, comparator)
|
|
||||||
if index == -1 {
|
|
||||||
result = append(result, slice[i])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,19 +452,20 @@ func FindLastBy[T any](slice []T, predicate func(index int, item T) bool) (v T,
|
|||||||
// Flatten flattens slice with one level.
|
// Flatten flattens slice with one level.
|
||||||
// Play: https://go.dev/play/p/hYa3cBEevtm
|
// Play: https://go.dev/play/p/hYa3cBEevtm
|
||||||
func Flatten(slice any) any {
|
func Flatten(slice any) any {
|
||||||
sv := sliceValue(slice)
|
sv := reflect.ValueOf(slice)
|
||||||
|
if sv.Kind() != reflect.Slice {
|
||||||
var result reflect.Value
|
panic("Flatten: input must be a slice")
|
||||||
if sv.Type().Elem().Kind() == reflect.Interface {
|
|
||||||
result = reflect.MakeSlice(reflect.TypeOf([]interface{}{}), 0, sv.Len())
|
|
||||||
} else if sv.Type().Elem().Kind() == reflect.Slice {
|
|
||||||
result = reflect.MakeSlice(sv.Type().Elem(), 0, sv.Len())
|
|
||||||
} else {
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elemType := sv.Type().Elem()
|
||||||
|
if elemType.Kind() == reflect.Slice {
|
||||||
|
elemType = elemType.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
result := reflect.MakeSlice(reflect.SliceOf(elemType), 0, sv.Len())
|
||||||
|
|
||||||
for i := 0; i < sv.Len(); i++ {
|
for i := 0; i < sv.Len(); i++ {
|
||||||
item := reflect.ValueOf(sv.Index(i).Interface())
|
item := sv.Index(i)
|
||||||
if item.Kind() == reflect.Slice {
|
if item.Kind() == reflect.Slice {
|
||||||
for j := 0; j < item.Len(); j++ {
|
for j := 0; j < item.Len(); j++ {
|
||||||
result = reflect.Append(result, item.Index(j))
|
result = reflect.Append(result, item.Index(j))
|
||||||
@@ -607,7 +637,7 @@ func Repeat[T any](item T, n int) []T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceSlice convert param to slice of interface.
|
// InterfaceSlice convert param to slice of interface.
|
||||||
// This function is deprecated, use generics feature of go1.18+ for replacement.
|
// deprecated: use generics feature of go1.18+ for replacement.
|
||||||
// Play: https://go.dev/play/p/FdQXF0Vvqs-
|
// Play: https://go.dev/play/p/FdQXF0Vvqs-
|
||||||
func InterfaceSlice(slice any) []any {
|
func InterfaceSlice(slice any) []any {
|
||||||
sv := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
@@ -624,7 +654,7 @@ func InterfaceSlice(slice any) []any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StringSlice convert param to slice of string.
|
// StringSlice convert param to slice of string.
|
||||||
// This function is deprecated, use generics feature of go1.18+ for replacement.
|
// deprecated: use generics feature of go1.18+ for replacement.
|
||||||
// Play: https://go.dev/play/p/W0TZDWCPFcI
|
// Play: https://go.dev/play/p/W0TZDWCPFcI
|
||||||
func StringSlice(slice any) []string {
|
func StringSlice(slice any) []string {
|
||||||
v := sliceValue(slice)
|
v := sliceValue(slice)
|
||||||
@@ -642,7 +672,7 @@ func StringSlice(slice any) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IntSlice convert param to slice of int.
|
// IntSlice convert param to slice of int.
|
||||||
// This function is deprecated, use generics feature of go1.18+ for replacement.
|
// deprecated: use generics feature of go1.18+ for replacement.
|
||||||
// Play: https://go.dev/play/p/UQDj-on9TGN
|
// Play: https://go.dev/play/p/UQDj-on9TGN
|
||||||
func IntSlice(slice any) []int {
|
func IntSlice(slice any) []int {
|
||||||
sv := sliceValue(slice)
|
sv := sliceValue(slice)
|
||||||
@@ -773,46 +803,54 @@ func InsertAt[T any](slice []T, index int, value any) []T {
|
|||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, ok := value.(T); ok {
|
switch v := value.(type) {
|
||||||
slice = append(slice[:index], append([]T{v}, slice[index:]...)...)
|
case T:
|
||||||
|
result := make([]T, size+1)
|
||||||
|
copy(result, slice[:index])
|
||||||
|
result[index] = v
|
||||||
|
copy(result[index+1:], slice[index:])
|
||||||
|
return result
|
||||||
|
case []T:
|
||||||
|
result := make([]T, size+len(v))
|
||||||
|
copy(result, slice[:index])
|
||||||
|
copy(result[index:], v)
|
||||||
|
copy(result[index+len(v):], slice[index:])
|
||||||
|
return result
|
||||||
|
default:
|
||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, ok := value.([]T); ok {
|
|
||||||
slice = append(slice[:index], append(v, slice[index:]...)...)
|
|
||||||
return slice
|
|
||||||
}
|
|
||||||
|
|
||||||
return slice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateAt update the slice element at index.
|
// UpdateAt update the slice element at index.
|
||||||
// Play: https://go.dev/play/p/f3mh2KloWVm
|
// Play: https://go.dev/play/p/f3mh2KloWVm
|
||||||
func UpdateAt[T any](slice []T, index int, value T) []T {
|
func UpdateAt[T any](slice []T, index int, value T) []T {
|
||||||
size := len(slice)
|
if index < 0 || index >= len(slice) {
|
||||||
|
|
||||||
if index < 0 || index >= size {
|
|
||||||
return slice
|
return slice
|
||||||
}
|
}
|
||||||
slice = append(slice[:index], append([]T{value}, slice[index+1:]...)...)
|
|
||||||
|
|
||||||
return slice
|
result := make([]T, len(slice))
|
||||||
|
copy(result, slice)
|
||||||
|
|
||||||
|
result[index] = value
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unique remove duplicate elements in slice.
|
// Unique remove duplicate elements in slice.
|
||||||
// Play: https://go.dev/play/p/AXw0R3ZTE6a
|
// Play: https://go.dev/play/p/AXw0R3ZTE6a
|
||||||
func Unique[T comparable](slice []T) []T {
|
func Unique[T comparable](slice []T) []T {
|
||||||
result := make([]T, 0, len(slice))
|
if len(slice) == 0 {
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
seen := make(map[T]struct{}, len(slice))
|
seen := make(map[T]struct{}, len(slice))
|
||||||
|
result := slice[:0]
|
||||||
|
|
||||||
for i := range slice {
|
for _, item := range slice {
|
||||||
if _, ok := seen[slice[i]]; ok {
|
if _, exists := seen[item]; !exists {
|
||||||
continue
|
seen[item] = struct{}{}
|
||||||
|
result = append(result, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
seen[slice[i]] = struct{}{}
|
|
||||||
|
|
||||||
result = append(result, slice[i])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -822,18 +860,19 @@ func Unique[T comparable](slice []T) []T {
|
|||||||
// The function maintains the order of the elements.
|
// The function maintains the order of the elements.
|
||||||
// Play: https://go.dev/play/p/GY7JE4yikrl
|
// Play: https://go.dev/play/p/GY7JE4yikrl
|
||||||
func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T {
|
func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T {
|
||||||
result := make([]T, 0, len(slice))
|
if len(slice) == 0 {
|
||||||
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
seen := make(map[U]struct{}, len(slice))
|
seen := make(map[U]struct{}, len(slice))
|
||||||
|
result := slice[:0]
|
||||||
|
|
||||||
for i := range slice {
|
for _, item := range slice {
|
||||||
key := iteratee(slice[i])
|
key := iteratee(item)
|
||||||
if _, ok := seen[key]; ok {
|
if _, exists := seen[key]; !exists {
|
||||||
continue
|
seen[key] = struct{}{}
|
||||||
|
result = append(result, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
seen[key] = struct{}{}
|
|
||||||
|
|
||||||
result = append(result, slice[i])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -843,19 +882,20 @@ func UniqueBy[T any, U comparable](slice []T, iteratee func(item T) U) []T {
|
|||||||
// The function maintains the order of the elements.
|
// The function maintains the order of the elements.
|
||||||
// Play: https://go.dev/play/p/rwSacr-ZHsR
|
// Play: https://go.dev/play/p/rwSacr-ZHsR
|
||||||
func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T {
|
func UniqueByComparator[T comparable](slice []T, comparator func(item T, other T) bool) []T {
|
||||||
result := make([]T, 0, len(slice))
|
if len(slice) == 0 {
|
||||||
seen := make([]T, 0, len(slice))
|
return slice
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]T, 0, len(slice))
|
||||||
for _, item := range slice {
|
for _, item := range slice {
|
||||||
duplicate := false
|
isDuplicate := false
|
||||||
for _, seenItem := range seen {
|
for _, existing := range result {
|
||||||
if comparator(item, seenItem) {
|
if comparator(item, existing) {
|
||||||
duplicate = true
|
isDuplicate = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !duplicate {
|
if !isDuplicate {
|
||||||
seen = append(seen, item)
|
|
||||||
result = append(result, item)
|
result = append(result, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user