slices in Go 1.21
Go 1.21中新增的 slices包中提供了很多与切片相关的函数,适用于任意类型的切片。本文内容来自官方文档
BinarySearch
函数签名如下:
func BinarySearchE, E cmp.Ordered](x S, target E) (int, bool)BinarySearch在已排序的切片中搜索 target 并返回找到 target 的位置,或者 target 在排序顺序中出现的位置;它还返回一个布尔值,表示是否确实在切片中找到了目标。切片必须按升序排序。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
n, found := slices.BinarySearch(names, "Vera")
fmt.Println("Vera:", n, found) // Vera: 2 true
n, found = slices.BinarySearch(names, "Bill")
fmt.Println("Bill:", n, found) // Bill: 1 false
}BinarySearchFunc
函数签名如下:
func BinarySearchFuncE, E, T any](x S, target T, cmp func(E, T) int) (int, bool)BinarySearchFunc的工作方式类似于BinarySearch,但使用自定义比较函数。切片必须按递增顺序排序,其中“递增”由cmp定义。如果切片元素与目标匹配,则cmp应返回0;如果切片元素在目标之前,则返回负数;如果切片元素在目标之后,则返回正数。cmp必须实现与切片相同的排序,这样如果cmp(a, t) < 0且cmp(b, t) >= 0,则切片中a必须位于b之前。
示例:
package main
import (
"cmp"
"fmt"
"slices"
)
func main() {
type Person struct {
Name string
Ageint
}
people := []Person{
{"Alice", 55},
{"Bob", 24},
{"Gopher", 13},
}
n, found := slices.BinarySearchFunc(people, Person{"Bob", 0}, func(a, b Person) int {
return cmp.Compare(a.Name, b.Name)
})
fmt.Println("Bob:", n, found) // Bob: 1 true
}Clip
函数签名如下:
func ClipE, E any](s S) SClip从切片中删除未使用的容量,返回s[:len(s):len(s)]。
Clone
函数签名如下:
func CloneE, E any](s S) SClone返回切片的副本。使用赋值来复制元素,因此这是浅拷贝。
Compact
函数签名如下:
func CompactE, E comparable](s S) SCompact用单个副本替换连续运行的相同元素。这类似于Unix上的uniq命令。Compact修改切片s的内容并返回修改后的切片,该切片的长度可能更小。当Compact总共丢弃m个元素时,它可能不会修改元素s。如果这些元素包含指针,可能要考虑将这些元素清零,以便它们引用的对象可以被回收。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
seq := []int{0, 1, 1, 2, 3, 5, 8}
seq = slices.Compact(seq)
fmt.Println(seq) //
}CompactFunc
函数签名如下:
func CompactFuncE, E any](s S, eq func(E, E) bool) SCompactFunc类似于Compact,但使用相等函数来比较元素。对于比较相等的元素运行,CompactFunc保留第一个。
示例:
package main
import (
"fmt"
"slices"
"strings"
)
func main() {
names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
names = slices.CompactFunc(names, func(a, b string) bool {
return strings.ToLower(a) == strings.ToLower(b)
})
fmt.Println(names) //
}Compare
函数签名如下:
func CompareE, E cmp.Ordered](s1, s2 S) intCompare对每对元素使用cmp.Compare来比较s1和s2的元素。从索引0开始按顺序比较元素,直到一个元素不等于另一个元素。返回第一个不匹配元素的比较结果。如果两个切片在其中一个结束之前都相等,则认为较短的切片小于较长的切片。如果s1 == s2,结果为0;如果s1 < s2,结果为-1;如果s1 > s2,结果为+1。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
fmt.Println("Equal:", slices.Compare(names, []string{"Alice", "Bob", "Vera"})) // Equal: 0
fmt.Println("V < X:", slices.Compare(names, []string{"Alice", "Bob", "Xena"})) // V < X: -1
fmt.Println("V > C:", slices.Compare(names, []string{"Alice", "Bob", "Cat"})) // V > C: 1
fmt.Println("3 > 2:", slices.Compare(names, []string{"Alice", "Bob"})) // 3 > 2: 1
}CompareFunc
函数签名如下:
func CompareFuncE1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) intCompareFunc类似于Compare,但对每对元素使用自定义比较函数。结果是cmp的第一个非零结果;如果cmp始终返回0:
[*]如果len(s1) == len(s2),则结果为0;
[*]如果len(s1) < len(s2),则结果为-1;
[*]如果len(s1) > len(s2),则结果为 +1。
示例:
import (
"cmp"
"fmt"
"slices"
"strconv"
)
func main() {
numbers := []int{0, 43, 8}
strings := []string{"0", "0", "8"}
result := slices.CompareFunc(numbers, strings, func(n int, s string) int {
sn, err := strconv.Atoi(s)
if err != nil {
return 1
}
return cmp.Compare(n, sn)
})
fmt.Println(result) // 1
}Contains
函数签名如下:
func ContainsE, E comparable](s S, v E) boolContains返回v是否存在于s中。
ContainsFunc
函数签名如下:
func ContainsFuncE, E any](s S, f func(E) bool) boolContainsFunc返回s中是否至少有一个元素e满足f(e)。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, -10, 8}
hasNegative := slices.ContainsFunc(numbers, func(n int) bool {
return n < 0
})
fmt.Println("Has a negative:", hasNegative) // Has a negative: true
hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
return n%2 != 0
})
fmt.Println("Has an odd number:", hasOdd) // Has an odd number: false
}Delete
函数签名如下:
func DeleteE, E any](s S, i, j int) SDelete从s中删除元素s,返回修改后的切片。如果s不是s的有效切片,则产生panic。删除的时间复杂度为O(len(s)-j),因此如果必须删除许多项,最好通过一次调用将它们全部删除,而不是一次删除一项。删除可能不会修改元素s。如果这些元素包含指针,还需要考虑将这些元素归零,以便它们引用的对象可以被回收。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
letters := []string{"a", "b", "c", "d", "e"}
letters = slices.Delete(letters, 1, 4)
fmt.Println(letters) //
}DeleteFunc
函数签名如下:
func DeleteFuncE, E any](s S, del func(E) bool) SDeleteFunc从s中删除函数del(e)返回true的所有元素,并返回修改后的切片。当DeleteFunc删除m个元素时,它可能不会修改元素s。如果这些元素包含指针,还需要考虑将这些元素归零,以便它们引用的对象可以被回收。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
seq := []int{0, 1, 1, 2, 3, 5, 8}
seq = slices.DeleteFunc(seq, func(n int) bool {
return n%2 != 0 // delete the odd numbers
})
fmt.Println(seq) //
}Equal
函数签名如下:
func EqualE, E comparable](s1, s2 S) boolEqual报告两个切片是否相等:长度相同且所有元素相等,返回true。如果长度不同,返回false。否则,按递增的索引顺序比较元素,并且比较在第一个不相等的对处停止。浮点NaN不被视为相等。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, 8}
fmt.Println(slices.Equal(numbers, []int{0, 42, 8})) // true
fmt.Println(slices.Equal(numbers, []int{10})) // false
}EqualFunc
func EqualFuncE1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) boolEqualFunc在每对元素上使用相等函数来报告两个切片是否相等。如果长度不同,EqualFunc返回false。否则,按递增索引顺序比较元素,并且比较在eq返回false的第一个索引处停止。
示例:
package main
import (
"fmt"
"slices"
"strconv"
)
func main() {
numbers := []int{0, 42, 8}
strings := []string{"000", "42", "0o10"}
equal := slices.EqualFunc(numbers, strings, func(n int, s string) bool {
sn, err := strconv.ParseInt(s, 0, 64)
if err != nil {
return false
}
return n == int(sn)
})
fmt.Println(equal) // true
}Grow
函数签名如下:
func GrowE, E any](s S, n int) S必要时,Grow会增加切片的容量,以保证另外n个元素的空间。在Grow(n)之后,至少可以将n个元素附加到切片,而无需再次分配。如果n为负数或太大而无法分配内存,Grow 会出现panic。
Index
函数签名如下:
func IndexE, E comparable](s S, v E) intIndex返回v在s中第一次出现的索引,如果不存在则返回-1。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, 8}
fmt.Println(slices.Index(numbers, 8)) // 2
fmt.Println(slices.Index(numbers, 7)) // -1
}IndexFunc
函数签名如下:
func IndexFuncE, E any](s S, f func(E) bool) intIndex返回s中第一次符合f(e)的元素的索引,如果不存在则返回-1。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
numbers := []int{0, 42, -10, 8}
i := slices.IndexFunc(numbers, func(n int) bool {
return n < 0
})
fmt.Println("First negative at index", i) // First negative at index 2
}Insert
函数签名如下:
func InsertE, E any](s S, i int, v ...E) SInsert将值v...插入到索引i处的s中,返回修改后的切片。s处的元素向上移动以腾出空间。在返回的切片r中,r == v,并且r == 最初位于r的值。如果i超出范围,则panic。该函数的复杂度为O(len(s) + len(v))。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
names := []string{"Alice", "Bob", "Vera"}
names = slices.Insert(names, 1, "Bill", "Billie")
names = slices.Insert(names, len(names), "Zac")
fmt.Println(names)//
}IsSorted
函数签名如下:
func IsSortedE, E cmp.Ordered](x S) boolIsSorted返回x是否按升序排序。
示例:
package main
import (
"fmt"
"slices"
)
func main() {
fmt.Println(slices.IsSorted([]string{"Alice", "Bob", "Vera"})) // true
fmt.Println(slices.IsSorted([]int{0, 2, 1})) // false
}IsSortedFunc
函数签名如下:
func IsSortedFuncE, E any](x S, cmp func(a, b E) int) bool IsSortedFunc返回x是否按升序排序,使用cmp作为比较函数。
示例:
package main
import (
"cmp"
"fmt"
"slices"
"strings"
)
func main() {
names := []string{"alice", "Bob", "VERA"}
isSortedInsensitive := slices.IsSortedFunc(names, func(a, b string) int {
return cmp.Compare(strings.ToLower(a), strings.ToLower(b))
})
fmt.Println(isSortedInsensitive) // true
fmt.Println(slices.IsSorted(names)) // false
}https://img2023.cnblogs.com/blog/1007709/202308/1007709-20230810162948167-1526955652.jpg声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]