123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- package otherutils
- import "fmt"
- // CompareResult represents the result of slice comparison
- type CompareResult int
- const (
- Different CompareResult = -1 // Elements are different
- SameUnordered CompareResult = 0 // Same elements but different order
- SameOrdered CompareResult = 1 // Same elements in same order
- )
- // RemoveFirst removes the first element that matches the predicate.
- // Note: This function modifies the original slice and does not preserve order
- // as it moves the last element to the removed position.
- func RemoveFirst[K any](sl []K, f func(v1 K) bool) []K {
- for k, v := range sl {
- if f(v) {
- sl[k] = sl[len(sl)-1]
- return sl[:len(sl)-1]
- }
- }
- return sl
- }
- // InSlice checks if a slice contains a specific element.
- func InSlice[K comparable](src []K, sub K) bool {
- for _, v := range src {
- if v == sub {
- return true
- }
- }
- return false
- }
- // RemoveSliceOrdered removes the first occurrence of sub from src while preserving order.
- // Returns the modified slice.
- func RemoveSliceOrdered[K comparable](src []K, sub K) []K {
- for k, v := range src {
- if v == sub {
- copy(src[k:], src[k+1:])
- return src[:len(src)-1]
- }
- }
- return src
- }
- // RemoveSliceUnordered removes the first occurrence of sub from src.
- // Note: This function does not preserve the original order as it moves
- // the last element to the removed position for better performance.
- func RemoveSliceUnordered[K comparable](src []K, sub K) []K {
- for k, v := range src {
- if v == sub {
- src[k] = src[len(src)-1]
- return src[:len(src)-1]
- }
- }
- return src
- }
- // RemoveOneFromSlice removes the first occurrence of an element that matches the predicate.
- func RemoveOneFromSlice[K any](src []K, cmp func(K) bool) []K {
- for k, v := range src {
- if cmp(v) {
- copy(src[k:], src[k+1:])
- return src[:len(src)-1]
- }
- }
- return src
- }
- // SubSlice returns a new slice containing elements from src that are not in sub.
- // Note: This function modifies the original slice to avoid memory allocation.
- // Example: [1,1,2,3] - [1,1,2,4] = [3]
- func SubSlice[K comparable](src []K, sub []K) []K {
- // 组织MAP表
- subMap := make(map[K]int, len(sub))
- for _, v := range sub {
- subMap[v] += 1
- }
- remove := func(val K) bool {
- v, ok := subMap[val]
- if !ok {
- return false
- }
- if v > 1 {
- subMap[val] -= 1
- } else {
- delete(subMap, val)
- }
- return true
- }
- index := 0
- for _, v := range src {
- if remove(v) {
- continue
- }
- src[index] = v
- index += 1
- }
- src = src[:index]
- return src
- }
- // CompareSlice compares two slices and returns the result.
- func CompareSlice[K comparable](p1 []K, p2 []K) CompareResult {
- // 长度不等直接-1
- if len(p1) != len(p2) {
- return Different
- }
- // 逐个比较每个相等则为1
- allEq := true
- for k, v := range p1 {
- if v != p2[k] {
- allEq = false
- break
- }
- }
- if allEq {
- return SameOrdered
- }
- // 个数统计,每个相等则为0
- p1Nums := make(map[K]int)
- for _, v := range p1 {
- p1Nums[v] += 1
- }
- p2Nums := make(map[K]int)
- for _, v := range p2 {
- p2Nums[v] += 1
- }
- if len(p1Nums) != len(p2Nums) {
- return Different
- }
- for k, v := range p1Nums {
- n := p2Nums[k]
- if n != v {
- return Different
- }
- }
- return SameUnordered
- }
- // CompareMap compares two maps and returns true if they are equal, false otherwise.
- func CompareMap[K comparable, V comparable](p1 map[K]V, p2 map[K]V) bool {
- //长度不等则为-1
- if len(p1) != len(p2) {
- return false
- }
- for k, v := range p1 {
- n, ok := p2[k]
- if !ok {
- return false
- }
- if n != v {
- return false
- }
- }
- return true
- }
- func CloneSlice[T any](slice []T) []T {
- newSlice := make([]T, len(slice))
- copy(newSlice, slice)
- return newSlice
- }
- func TestSlice() {
- //[1,1,2,3] - [1,1,2,4] = [3]
- fmt.Println(SubSlice([]int{1, 1, 2, 3}, []int{1, 1, 2, 4}))
- fmt.Println(SubSlice([]int{1, 1, 2, 3}, []int{}))
- fmt.Println(SubSlice([]int{}, []int{1, 1, 2, 4}))
- }
|