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})) }