code.gitea.io/gitea@v1.19.3/modules/util/slice.go (about) 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 // Most of the functions in this file can have better implementations with "golang.org/x/exp/slices". 5 // However, "golang.org/x/exp" is experimental and unreliable, we shouldn't use it. 6 // So lets waiting for the "slices" has be promoted to the main repository one day. 7 8 package util 9 10 import "strings" 11 12 // SliceContains returns true if the target exists in the slice. 13 func SliceContains[T comparable](slice []T, target T) bool { 14 return SliceContainsFunc(slice, func(t T) bool { return t == target }) 15 } 16 17 // SliceContainsFunc returns true if any element in the slice satisfies the targetFunc. 18 func SliceContainsFunc[T any](slice []T, targetFunc func(T) bool) bool { 19 for _, v := range slice { 20 if targetFunc(v) { 21 return true 22 } 23 } 24 return false 25 } 26 27 // SliceContainsString sequential searches if string exists in slice. 28 func SliceContainsString(slice []string, target string, insensitive ...bool) bool { 29 if len(insensitive) != 0 && insensitive[0] { 30 target = strings.ToLower(target) 31 return SliceContainsFunc(slice, func(t string) bool { return strings.ToLower(t) == target }) 32 } 33 34 return SliceContains(slice, target) 35 } 36 37 // SliceSortedEqual returns true if the two slices will be equal when they get sorted. 38 // It doesn't require that the slices have been sorted, and it doesn't sort them either. 39 func SliceSortedEqual[T comparable](s1, s2 []T) bool { 40 if len(s1) != len(s2) { 41 return false 42 } 43 44 counts := make(map[T]int, len(s1)) 45 for _, v := range s1 { 46 counts[v]++ 47 } 48 for _, v := range s2 { 49 counts[v]-- 50 } 51 52 for _, v := range counts { 53 if v != 0 { 54 return false 55 } 56 } 57 return true 58 } 59 60 // SliceEqual returns true if the two slices are equal. 61 func SliceEqual[T comparable](s1, s2 []T) bool { 62 if len(s1) != len(s2) { 63 return false 64 } 65 66 for i, v := range s1 { 67 if s2[i] != v { 68 return false 69 } 70 } 71 return true 72 } 73 74 // SliceRemoveAll removes all the target elements from the slice. 75 func SliceRemoveAll[T comparable](slice []T, target T) []T { 76 return SliceRemoveAllFunc(slice, func(t T) bool { return t == target }) 77 } 78 79 // SliceRemoveAllFunc removes all elements which satisfy the targetFunc from the slice. 80 func SliceRemoveAllFunc[T comparable](slice []T, targetFunc func(T) bool) []T { 81 idx := 0 82 for _, v := range slice { 83 if targetFunc(v) { 84 continue 85 } 86 slice[idx] = v 87 idx++ 88 } 89 return slice[:idx] 90 }