242 lines
4.4 KiB
Go
242 lines
4.4 KiB
Go
|
|
package slicex
|
||
|
|
|
||
|
|
import (
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
gox "git.cloudyne.io/go/hiscaler-gox"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Map values all value execute f function, and return a new slice
|
||
|
|
//
|
||
|
|
// Example
|
||
|
|
//
|
||
|
|
// Map([]string{"A", "B", "C"}, func(v string) string {
|
||
|
|
// return strings.ToLower(v)
|
||
|
|
// })
|
||
|
|
// // Output: ["a", "b", "c"]
|
||
|
|
func Map[T comparable](values []T, f func(v T) T) []T {
|
||
|
|
items := make([]T, len(values))
|
||
|
|
for i, v := range values {
|
||
|
|
items[i] = f(v)
|
||
|
|
}
|
||
|
|
return items
|
||
|
|
}
|
||
|
|
|
||
|
|
// Filter return matched f function condition value
|
||
|
|
//
|
||
|
|
// Example:
|
||
|
|
//
|
||
|
|
// Filter([]int{0, 1, 2, 3}, func(v int) bool {
|
||
|
|
// return v > 0
|
||
|
|
// })
|
||
|
|
// // Output: [1, 2, 3]
|
||
|
|
func Filter[T comparable](values []T, f func(v T) bool) []T {
|
||
|
|
items := make([]T, 0)
|
||
|
|
for _, v := range values {
|
||
|
|
if ok := f(v); ok {
|
||
|
|
items = append(items, v)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return items
|
||
|
|
}
|
||
|
|
|
||
|
|
func ToInterface[T gox.Number | ~string](values []T) []interface{} {
|
||
|
|
if values == nil || len(values) == 0 {
|
||
|
|
return []interface{}{}
|
||
|
|
}
|
||
|
|
|
||
|
|
ifs := make([]interface{}, len(values))
|
||
|
|
for i, value := range values {
|
||
|
|
ifs[i] = value
|
||
|
|
}
|
||
|
|
return ifs
|
||
|
|
}
|
||
|
|
|
||
|
|
// StringToInterface Change string slice to interface slice
|
||
|
|
func StringToInterface(values []string) []interface{} {
|
||
|
|
return ToInterface(values)
|
||
|
|
}
|
||
|
|
|
||
|
|
// IntToInterface Change int slice to interface slice
|
||
|
|
func IntToInterface(values []int) []interface{} {
|
||
|
|
return ToInterface(values)
|
||
|
|
}
|
||
|
|
|
||
|
|
// StringSliceEqual Check a, b is equal
|
||
|
|
func StringSliceEqual(a, b []string, caseSensitive, ignoreEmpty, trim bool) bool {
|
||
|
|
if a == nil && b == nil {
|
||
|
|
return true
|
||
|
|
} else if a == nil || b == nil {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
if !caseSensitive || ignoreEmpty || trim {
|
||
|
|
fixFunc := func(ss []string) []string {
|
||
|
|
if len(ss) == 0 {
|
||
|
|
return ss
|
||
|
|
}
|
||
|
|
values := make([]string, 0)
|
||
|
|
for _, s := range ss {
|
||
|
|
if trim {
|
||
|
|
s = strings.TrimSpace(s)
|
||
|
|
}
|
||
|
|
if s == "" && ignoreEmpty {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if !caseSensitive {
|
||
|
|
s = strings.ToUpper(s)
|
||
|
|
}
|
||
|
|
values = append(values, s)
|
||
|
|
}
|
||
|
|
return values
|
||
|
|
}
|
||
|
|
a = fixFunc(a)
|
||
|
|
b = fixFunc(b)
|
||
|
|
}
|
||
|
|
if len(a) != len(b) {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, av := range a {
|
||
|
|
exists := false
|
||
|
|
for _, bv := range b {
|
||
|
|
if av == bv {
|
||
|
|
exists = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if !exists {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
// IntSliceEqual Check a, b is equal
|
||
|
|
func IntSliceEqual(a, b []int) bool {
|
||
|
|
if a == nil && b == nil {
|
||
|
|
return true
|
||
|
|
} else if a == nil || b == nil || len(a) != len(b) {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, av := range a {
|
||
|
|
exists := false
|
||
|
|
for _, bv := range b {
|
||
|
|
if av == bv {
|
||
|
|
exists = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if !exists {
|
||
|
|
return false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
|
||
|
|
func StringSliceReverse(ss []string) []string {
|
||
|
|
n := len(ss)
|
||
|
|
if n <= 1 {
|
||
|
|
return ss
|
||
|
|
}
|
||
|
|
|
||
|
|
vv := make([]string, len(ss))
|
||
|
|
copy(vv, ss)
|
||
|
|
for k1 := 0; k1 < n/2; k1++ {
|
||
|
|
k2 := n - k1 - 1
|
||
|
|
vv[k1], vv[k2] = vv[k2], vv[k1]
|
||
|
|
}
|
||
|
|
return vv
|
||
|
|
}
|
||
|
|
|
||
|
|
func IntSliceReverse(ss []int) []int {
|
||
|
|
n := len(ss)
|
||
|
|
if n <= 1 {
|
||
|
|
return ss
|
||
|
|
}
|
||
|
|
|
||
|
|
vv := make([]int, len(ss))
|
||
|
|
copy(vv, ss)
|
||
|
|
for k1 := 0; k1 < n/2; k1++ {
|
||
|
|
k2 := n - k1 - 1
|
||
|
|
vv[k1], vv[k2] = vv[k2], vv[k1]
|
||
|
|
}
|
||
|
|
return vv
|
||
|
|
}
|
||
|
|
|
||
|
|
// Diff return a slice in ss[0] and not in ss[1:]
|
||
|
|
func Diff[T comparable](values ...[]T) []T {
|
||
|
|
diffValues := make([]T, 0)
|
||
|
|
n := len(values)
|
||
|
|
if n == 0 || values[0] == nil {
|
||
|
|
return diffValues
|
||
|
|
} else if n == 1 {
|
||
|
|
return values[0]
|
||
|
|
} else {
|
||
|
|
items := make(map[T]struct{}, 0)
|
||
|
|
for _, vs := range values[1:] {
|
||
|
|
for _, v := range vs {
|
||
|
|
items[v] = struct{}{}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for _, v := range values[0] {
|
||
|
|
if _, ok := items[v]; !ok {
|
||
|
|
diffValues = append(diffValues, v)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return diffValues
|
||
|
|
}
|
||
|
|
|
||
|
|
func StringSliceDiff(ss ...[]string) []string {
|
||
|
|
diffValues := make([]string, 0)
|
||
|
|
if len(ss) == 0 || ss[0] == nil {
|
||
|
|
return diffValues
|
||
|
|
} else if len(ss) == 1 {
|
||
|
|
return ss[0]
|
||
|
|
} else {
|
||
|
|
for _, v1 := range ss[0] {
|
||
|
|
exists := false
|
||
|
|
for _, items := range ss[1:] {
|
||
|
|
for _, v2 := range items {
|
||
|
|
if strings.EqualFold(v1, v2) {
|
||
|
|
exists = true
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if exists {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if !exists {
|
||
|
|
diffValues = append(diffValues, v1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return diffValues
|
||
|
|
}
|
||
|
|
|
||
|
|
func IntSliceDiff(ss ...[]int) []int {
|
||
|
|
return Diff(ss...)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Chunk chunks a slice by size
|
||
|
|
func Chunk[T comparable](items []T, size int) [][]T {
|
||
|
|
chunkItems := make([][]T, 0)
|
||
|
|
n := len(items)
|
||
|
|
if items == nil || n == 0 {
|
||
|
|
return chunkItems
|
||
|
|
} else if size <= 0 {
|
||
|
|
return [][]T{items}
|
||
|
|
}
|
||
|
|
for i := 0; i < n; i += size {
|
||
|
|
end := i + size
|
||
|
|
if end > n {
|
||
|
|
end = n
|
||
|
|
}
|
||
|
|
chunkItems = append(chunkItems, items[i:end])
|
||
|
|
}
|
||
|
|
return chunkItems
|
||
|
|
}
|