wp-go/helper/slice/set.go
2023-03-09 22:36:41 +08:00

161 lines
2.5 KiB
Go

package slice
func IsContained[T comparable](arr []T, a T) bool {
for _, v := range arr {
if a == v {
return true
}
}
return false
}
func IsContainedByFn[T any](a []T, e T, fn func(i, j T) bool) bool {
for _, t := range a {
if fn(e, t) {
return true
}
}
return false
}
// Diff return elements which in a and not in b,...
func Diff[T comparable](a []T, b ...[]T) (r []T) {
for _, t := range a {
f := false
for _, ts := range b {
if IsContained(ts, t) {
f = true
break
}
}
if f {
continue
}
r = append(r, t)
}
return
}
func DiffByFn[T any](a []T, fn func(i, j T) bool, b ...[]T) (r []T) {
for _, t := range a {
f := false
for _, ts := range b {
if IsContainedByFn(ts, t, fn) {
f = true
break
}
}
if f {
continue
}
r = append(r, t)
}
return
}
func DiffNewByFn[T, V any](a []T, fn func(i, j T) bool, fnV func(T) V, b ...[]T) (r []V) {
for _, t := range a {
f := false
for _, ts := range b {
if IsContainedByFn(ts, t, fn) {
f = true
break
}
}
if f {
continue
}
r = append(r, fnV(t))
}
return
}
func Intersect[T comparable](a []T, b ...[]T) (r []T) {
for _, t := range a {
f := false
for _, ts := range b {
if !IsContained(ts, t) {
f = true
break
}
}
if f {
continue
}
r = append(r, t)
}
return
}
func IntersectByFn[T any](a []T, fn func(i, j T) bool, b ...[]T) (r []T) {
for _, t := range a {
f := false
for _, ts := range b {
if !IsContainedByFn(ts, t, fn) {
f = true
break
}
}
if f {
continue
}
r = append(r, t)
}
return
}
func IntersectNewByFn[T, V any](a []T, fn func(i, j T) bool, fnV func(T) V, b ...[]T) (r []V) {
for _, t := range a {
f := false
for _, ts := range b {
if !IsContainedByFn(ts, t, fn) {
f = true
break
}
}
if f {
continue
}
r = append(r, fnV(t))
}
return
}
func Unique[T comparable](a ...[]T) (r []T) {
m := map[T]struct{}{}
for _, ts := range a {
for _, t := range ts {
if _, ok := m[t]; !ok {
m[t] = struct{}{}
r = append(r, t)
} else {
continue
}
}
}
return
}
func UniqueByFn[T any](fn func(T, T) bool, a ...[]T) (r []T) {
for _, ts := range a {
for _, t := range ts {
if !IsContainedByFn(r, t, fn) {
r = append(r, t)
}
}
}
return r
}
func UniqueNewByFn[T, V any](fn func(T, T) bool, fnVal func(T) V, a ...[]T) (r []V) {
var rr []T
for _, ts := range a {
for _, t := range ts {
if !IsContainedByFn(rr, t, fn) {
rr = append(rr, t)
r = append(r, fnVal(t))
}
}
}
return r
}