package slices

import "slices"

Package slices 定义了对任何类型的切片都有用的各种函数。

Index

Examples

Functions

func All

func All[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]

All 返回切片中索引-值对的迭代器,按通常的顺序。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	for i, v := range slices.All(names) {
		fmt.Println(i, ":", v)
	}
}

Output:

0 : Alice
1 : Bob
2 : Vera

func AppendSeq

func AppendSeq[Slice ~[]E, E any](s Slice, seq iter.Seq[E]) Slice

AppendSeq 将 seq 中的值追加到切片并返回扩展后的切片。 如果 seq 为空,结果保留 s 的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	seq := func(yield func(int) bool) {
		for i := 0; i < 10; i += 2 {
			if !yield(i) {
				return
			}
		}
	}

	s := slices.AppendSeq([]int{1, 2}, seq)
	fmt.Println(s)
}

Output:

[1 2 0 2 4 6 8]

func Backward

func Backward[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]

Backward 返回切片中索引-值对的迭代器, 以降序索引反向遍历。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	for i, v := range slices.Backward(names) {
		fmt.Println(i, ":", v)
	}
}

Output:

2 : Vera
1 : Bob
0 : Alice

func BinarySearch

func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)

BinarySearch 在已排序的切片中搜索 target,并返回找到 target 的最早位置, 或者 target 在排序顺序中应该出现的位置;它还返回一个布尔值, 说明 target 是否真的在切片中找到。切片必须按升序排序。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	n, found := slices.BinarySearch(names, "Vera")
	fmt.Println("Vera:", n, found)
	n, found = slices.BinarySearch(names, "Bill")
	fmt.Println("Bill:", n, found)
}

Output:

Vera: 2 true
Bill: 1 false

func BinarySearchFunc

func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)

BinarySearchFunc 的工作方式与 BinarySearch 类似,但使用自定义比较函数。 切片必须按升序排序,其中"升序"由 cmp 定义。 cmp 应该在切片元素与 target 匹配时返回 0, 如果切片元素在 target 之前则返回负数, 如果切片元素在 target 之后则返回正数。 cmp 必须实现与切片相同的排序,使得如果 cmp(a, t) < 0 且 cmp(b, t) >= 0, 则 a 必须在切片中排在 b 之前。

Example
package main

import (
	"fmt"
	"slices"
	"strings"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	people := []Person{
		{"Alice", 55},
		{"Bob", 24},
		{"Gopher", 13},
	}
	n, found := slices.BinarySearchFunc(people, Person{"Bob", 0}, func(a, b Person) int {
		return strings.Compare(a.Name, b.Name)
	})
	fmt.Println("Bob:", n, found)
}

Output:

Bob: 1 true

func Chunk

func Chunk[Slice ~[]E, E any](s Slice, n int) iter.Seq[Slice]

Chunk 返回 s 的最多 n 个元素的连续子切片的迭代器。 除最后一个子切片外,所有子切片的大小都为 n。 所有子切片都被裁剪为没有超出长度的容量。 如果 s 为空,则序列为空:序列中没有空切片。 如果 n 小于 1,Chunk 会 panic。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}

	type People []Person

	people := People{
		{"Gopher", 13},
		{"Alice", 20},
		{"Bob", 5},
		{"Vera", 24},
		{"Zac", 15},
	}

	// Chunk people into []Person 2 elements at a time.
	for c := range slices.Chunk(people, 2) {
		fmt.Println(c)
	}

}

Output:

[{Gopher 13} {Alice 20}]
[{Bob 5} {Vera 24}]
[{Zac 15}]

func Clip

func Clip[S ~[]E, E any](s S) S

Clip 从切片中移除未使用的容量,返回 s[:len(s):len(s)]。 结果保留 s 的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	a := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	s := a[:4:10]
	clip := slices.Clip(s)
	fmt.Println(cap(s))
	fmt.Println(clip)
	fmt.Println(len(clip))
	fmt.Println(cap(clip))
}

Output:

10
[0 1 2 3]
4
4

func Clone

func Clone[S ~[]E, E any](s S) S

Clone 返回切片的副本。 元素通过赋值复制,因此这是浅拷贝。 结果可能有额外的未使用容量。 结果保留 s 的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, -10, 8}
	clone := slices.Clone(numbers)
	fmt.Println(clone)
	clone[2] = 10
	fmt.Println(numbers)
	fmt.Println(clone)
}

Output:

[0 42 -10 8]
[0 42 -10 8]
[0 42 10 8]

func Collect

func Collect[E any](seq iter.Seq[E]) []E

Collect 将 seq 中的值收集到一个新切片中并返回。 如果 seq 为空,结果为 nil。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	seq := func(yield func(int) bool) {
		for i := 0; i < 10; i += 2 {
			if !yield(i) {
				return
			}
		}
	}

	s := slices.Collect(seq)
	fmt.Println(s)
}

Output:

[0 2 4 6 8]

func Compact

func Compact[S ~[]E, E comparable](s S) S

Compact 用单个副本替换连续相等的元素运行。 这类似于 Unix 上的 uniq 命令。 Compact 修改切片 s 的内容并返回修改后的切片, 其长度可能较小。 Compact 将新长度与原始长度之间的元素置零。 结果保留 s 的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	seq := []int{0, 1, 1, 2, 3, 5, 8}
	seq = slices.Compact(seq)
	fmt.Println(seq)
}

Output:

[0 1 2 3 5 8]

func CompactFunc

func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S

CompactFunc 类似于 Compact,但使用等值函数比较元素。 对于比较相等的元素运行,CompactFunc 保留第一个。 CompactFunc 将新长度与原始长度之间的元素置零。 结果保留 s 的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
	"strings"
)

func main() {
	names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
	names = slices.CompactFunc(names, strings.EqualFold)
	fmt.Println(names)
}

Output:

[bob alice Vera]

func Compare

func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int

Compare 使用 cmp.Compare 对每对元素进行比较。 元素按顺序比较,从索引 0 开始,直到有一个元素与另一个不相等。 返回第一个不匹配元素的比较结果。 如果两个切片在其中一个结束时之前都相等,则认为较短的切片比较长的切片小。 结果为 0 表示 s1 == s2,-1 表示 s1 < s2,+1 表示 s1 > s2。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	fmt.Println("Equal:", slices.Compare(names, []string{"Alice", "Bob", "Vera"}))
	fmt.Println("V < X:", slices.Compare(names, []string{"Alice", "Bob", "Xena"}))
	fmt.Println("V > C:", slices.Compare(names, []string{"Alice", "Bob", "Cat"}))
	fmt.Println("3 > 2:", slices.Compare(names, []string{"Alice", "Bob"}))
}

Output:

Equal: 0
V < X: -1
V > C: 1
3 > 2: 1

func CompareFunc

func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int

CompareFunc 类似于 Compare,但对每对元素使用自定义比较函数。 结果是 cmp 的第一个非零结果;如果 cmp 始终返回 0, 则结果为 0(如果 len(s1) == len(s2)),-1(如果 len(s1) < len(s2)), +1(如果 len(s1) > len(s2))。

Example
package main

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

Output:

1

func Concat

func Concat[S ~[]E, E any](slices ...S) S

Concat 返回一个新切片,连接传入的切片。 如果连接为空,结果为 nil。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	s1 := []int{0, 1, 2, 3}
	s2 := []int{4, 5, 6}
	concat := slices.Concat(s1, s2)
	fmt.Println(concat)
}

Output:

[0 1 2 3 4 5 6]

func Contains

func Contains[S ~[]E, E comparable](s S, v E) bool

Contains 报告 v 是否存在于 s 中。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 1, 2, 3}
	fmt.Println(slices.Contains(numbers, 2))
	fmt.Println(slices.Contains(numbers, 4))
}

Output:

true
false

func ContainsFunc

func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool

ContainsFunc 报告是否存在至少一个 s 中的元素 e 满足 f(e)。

Example
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)
	hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
		return n%2 != 0
	})
	fmt.Println("Has an odd number:", hasOdd)
}

Output:

Has a negative: true
Has an odd number: false

func Delete

func Delete[S ~[]E, E any](s S, i, j int) S

Delete 从 s 中移除元素 s[i:j],返回修改后的切片。 如果 j > len(s) 或 s[i:j] 不是 s 的有效切片,Delete 会 panic。 Delete 的时间复杂度为 O(len(s)-i),因此如果需要删除多个元素, 最好一次性调用删除所有元素,而不是一次删除一个。 Delete 会将元素 s[len(s)-(j-i):len(s)] 置零。 如果结果为空,它与 s 具有相同的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	letters := []string{"a", "b", "c", "d", "e"}
	letters = slices.Delete(letters, 1, 4)
	fmt.Println(letters)
}

Output:

[a e]

func DeleteFunc

func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S

DeleteFunc 从 s 中移除任何使 del 返回 true 的元素,返回修改后的切片。 DeleteFunc 会将新长度与原始长度之间的元素置零。 如果结果为空,它与 s 具有相同的 nil 性质。

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

Output:

[0 2 8]

func Equal

func Equal[S ~[]E, E comparable](s1, s2 S) bool

Equal 报告两个切片是否相等:相同的长度且所有元素都相等。 如果长度不同,Equal 返回 false。 否则,按递增索引顺序比较元素,并在第一对不相等的元素处停止比较。 空切片和 nil 切片被认为是相等的。 浮点数 NaN 不被认为是相等的。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, 8}
	fmt.Println(slices.Equal(numbers, []int{0, 42, 8}))
	fmt.Println(slices.Equal(numbers, []int{10}))
}

Output:

true
false

func EqualFunc

func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool

EqualFunc 使用等值函数对每对元素进行比较,报告两个切片是否相等。 如果长度不同,EqualFunc 返回 false。 否则,按递增索引顺序比较元素,并在第一个使 eq 返回 false 的索引处停止比较。

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

Output:

true

func Grow

func Grow[S ~[]E, E any](s S, n int) S

Grow 在必要时增加切片的容量,以保证另外 n 个元素的空间。 在 Grow(n) 之后,至少可以追加 n 个元素到切片而无需再次分配。 如果 n 为负数或太大无法分配内存,Grow 会 panic。 结果保留 s 的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, -10, 8}
	grow := slices.Grow(numbers, 2)
	fmt.Println(cap(numbers))
	fmt.Println(grow)
	fmt.Println(len(grow))
	fmt.Println(cap(grow))
}

Output:

4
[0 42 -10 8]
4
8

func Index

func Index[S ~[]E, E comparable](s S, v E) int

Index 返回 v 在 s 中第一次出现的索引, 如果不存在则返回 -1。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, 8}
	fmt.Println(slices.Index(numbers, 8))
	fmt.Println(slices.Index(numbers, 7))
}

Output:

2
-1

func IndexFunc

func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int

IndexFunc 返回满足 f(s[i]) 的第一个索引 i, 如果没有满足条件的则返回 -1。

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

Output:

First negative at index 2

func Insert

func Insert[S ~[]E, E any](s S, i int, v ...E) S

Insert 将值 v... 插入到 s 的索引 i 处, 返回修改后的切片。 s[i:] 中的元素向上移动以腾出空间。 在返回的切片 r 中,r[i] == v[0], 并且如果 i < len(s),则 r[i+len(v)] == 原本在 s[i] 处的值。 如果 i > len(s),Insert 会 panic。 此函数的时间复杂度为 O(len(s) + len(v))。 如果结果为空,它与 s 具有相同的 nil 性质。

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

Output:

[Alice Bill Billie Bob Vera Zac]

func IsSorted

func IsSorted[S ~[]E, E cmp.Ordered](x S) bool

IsSorted 报告 x 是否按升序排序。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	fmt.Println(slices.IsSorted([]string{"Alice", "Bob", "Vera"}))
	fmt.Println(slices.IsSorted([]int{0, 2, 1}))
}

Output:

true
false

func IsSortedFunc

func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool

IsSortedFunc 报告 x 是否按升序排序,cmp 作为 SortFunc 所定义的比较函数。

Example
package main

import (
	"fmt"
	"slices"
	"strings"
)

func main() {
	names := []string{"alice", "Bob", "VERA"}
	isSortedInsensitive := slices.IsSortedFunc(names, func(a, b string) int {
		return strings.Compare(strings.ToLower(a), strings.ToLower(b))
	})
	fmt.Println(isSortedInsensitive)
	fmt.Println(slices.IsSorted(names))
}

Output:

true
false

func Max

func Max[S ~[]E, E cmp.Ordered](x S) E

Max 返回 x 中的最大值。如果 x 为空,它会 panic。 对于浮点数 E,Max 传播 NaN(x 中的任何 NaN 值都会使输出为 NaN)。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, -10, 8}
	fmt.Println(slices.Max(numbers))
}

Output:

42

func MaxFunc

func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E

MaxFunc 返回 x 中的最大值,使用 cmp 比较元素。 如果 x 为空,它会 panic。如果根据 cmp 函数有多个最大元素, MaxFunc 返回第一个。

Example
package main

import (
	"cmp"
	"fmt"
	"slices"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	people := []Person{
		{"Gopher", 13},
		{"Alice", 55},
		{"Vera", 24},
		{"Bob", 55},
	}
	firstOldest := slices.MaxFunc(people, func(a, b Person) int {
		return cmp.Compare(a.Age, b.Age)
	})
	fmt.Println(firstOldest.Name)
}

Output:

Alice

func Min

func Min[S ~[]E, E cmp.Ordered](x S) E

Min 返回 x 中的最小值。如果 x 为空,它会 panic。 对于浮点数,Min 传播 NaN(x 中的任何 NaN 值都会使输出为 NaN)。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 42, -10, 8}
	fmt.Println(slices.Min(numbers))
}

Output:

-10

func MinFunc

func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E

MinFunc 返回 x 中的最小值,使用 cmp 比较元素。 如果 x 为空,它会 panic。如果根据 cmp 函数有多个最小元素, MinFunc 返回第一个。

Example
package main

import (
	"cmp"
	"fmt"
	"slices"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	people := []Person{
		{"Gopher", 13},
		{"Bob", 5},
		{"Vera", 24},
		{"Bill", 5},
	}
	firstYoungest := slices.MinFunc(people, func(a, b Person) int {
		return cmp.Compare(a.Age, b.Age)
	})
	fmt.Println(firstYoungest.Name)
}

Output:

Bob

func Repeat

func Repeat[S ~[]E, E any](x S, count int) S

Repeat 返回一个新切片,将提供的切片重复指定次数。 结果的长度和容量为 (len(x) * count)。 结果永远不为 nil。 如果 count 为负数,或 (len(x) * count) 的结果溢出,Repeat 会 panic。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	numbers := []int{0, 1, 2, 3}
	repeat := slices.Repeat(numbers, 2)
	fmt.Println(repeat)
}

Output:

[0 1 2 3 0 1 2 3]

func Replace

func Replace[S ~[]E, E any](s S, i, j int, v ...E) S

Replace 用给定的 v 替换元素 s[i:j],并返回修改后的切片。 如果 j > len(s) 或 s[i:j] 不是 s 的有效切片,Replace 会 panic。 当 len(v) < (j-i) 时,Replace 会将新长度与原始长度之间的元素置零。 如果结果为空,它与 s 具有相同的 nil 性质。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera", "Zac"}
	names = slices.Replace(names, 1, 3, "Bill", "Billie", "Cat")
	fmt.Println(names)
}

Output:

[Alice Bill Billie Cat Zac]

func Reverse

func Reverse[S ~[]E, E any](s S)

Reverse 就地反转切片的元素。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"alice", "Bob", "VERA"}
	slices.Reverse(names)
	fmt.Println(names)
}

Output:

[VERA Bob alice]

func Sort

func Sort[S ~[]E, E cmp.Ordered](x S)

Sort 按升序对任何可排序类型的切片进行排序。 在对浮点数进行排序时,NaN 排在其他值之前。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	smallInts := []int8{0, 42, -10, 8}
	slices.Sort(smallInts)
	fmt.Println(smallInts)
}

Output:

[-10 0 8 42]

func SortFunc

func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int)

SortFunc 根据 cmp 函数确定的方式对切片 x 按升序排序。 此排序不保证是稳定的。 cmp(a, b) 应该在 a < b 时返回负数,在 a > b 时返回正数, 在 a == b 或 a 和 b 以严格弱序而言不可比较时返回零。

SortFunc 要求 cmp 是严格弱序。 参见 https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings。 对于不可比较的项,函数应返回 0。

Example (CaseInsensitive)
package main

import (
	"fmt"
	"slices"
	"strings"
)

func main() {
	names := []string{"Bob", "alice", "VERA"}
	slices.SortFunc(names, func(a, b string) int {
		return strings.Compare(strings.ToLower(a), strings.ToLower(b))
	})
	fmt.Println(names)
}

Output:

[alice Bob VERA]
Example (MultiField)
package main

import (
	"cmp"
	"fmt"
	"slices"
	"strings"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	people := []Person{
		{"Gopher", 13},
		{"Alice", 55},
		{"Bob", 24},
		{"Alice", 20},
	}
	slices.SortFunc(people, func(a, b Person) int {
		if n := strings.Compare(a.Name, b.Name); n != 0 {
			return n
		}
		// If names are equal, order by age
		return cmp.Compare(a.Age, b.Age)
	})
	fmt.Println(people)
}

Output:

[{Alice 20} {Alice 55} {Bob 24} {Gopher 13}]

func SortStableFunc

func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int)

SortStableFunc 对切片 x 进行排序,同时保持相等元素的原始顺序, 使用 cmp 以与 SortFunc 相同的方式比较元素。

Example
package main

import (
	"fmt"
	"slices"
	"strings"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}
	people := []Person{
		{"Gopher", 13},
		{"Alice", 20},
		{"Bob", 24},
		{"Alice", 55},
	}
	// Stable sort by name, keeping age ordering of Alice intact
	slices.SortStableFunc(people, func(a, b Person) int {
		return strings.Compare(a.Name, b.Name)
	})
	fmt.Println(people)
}

Output:

[{Alice 20} {Alice 55} {Bob 24} {Gopher 13}]

func Sorted

func Sorted[E cmp.Ordered](seq iter.Seq[E]) []E

Sorted 将 seq 中的值收集到一个新切片中,对切片进行排序,然后返回。 如果 seq 为空,结果为 nil。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	seq := func(yield func(int) bool) {
		flag := -1
		for i := 0; i < 10; i += 2 {
			flag = -flag
			if !yield(i * flag) {
				return
			}
		}
	}

	s := slices.Sorted(seq)
	fmt.Println(s)
	fmt.Println(slices.IsSorted(s))
}

Output:

[-6 -2 0 4 8]
true

func SortedFunc

func SortedFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E

SortedFunc 将 seq 中的值收集到一个新切片中,使用比较函数对切片进行排序,然后返回。 如果 seq 为空,结果为 nil。

Example
package main

import (
	"cmp"
	"fmt"
	"slices"
)

func main() {
	seq := func(yield func(int) bool) {
		flag := -1
		for i := 0; i < 10; i += 2 {
			flag = -flag
			if !yield(i * flag) {
				return
			}
		}
	}

	sortFunc := func(a, b int) int {
		return cmp.Compare(b, a) // the comparison is being done in reverse
	}

	s := slices.SortedFunc(seq, sortFunc)
	fmt.Println(s)
}

Output:

[8 4 0 -2 -6]

func SortedStableFunc

func SortedStableFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E

SortedStableFunc 将 seq 中的值收集到一个新切片中。 然后使用比较函数对切片进行排序,同时保持相等元素的原始顺序。 它返回新的切片。 如果 seq 为空,结果为 nil。

Example
package main

import (
	"cmp"
	"fmt"
	"slices"
)

func main() {
	type Person struct {
		Name string
		Age  int
	}

	people := []Person{
		{"Gopher", 13},
		{"Alice", 20},
		{"Bob", 5},
		{"Vera", 24},
		{"Zac", 20},
	}

	sortFunc := func(x, y Person) int {
		return cmp.Compare(x.Age, y.Age)
	}

	s := slices.SortedStableFunc(slices.Values(people), sortFunc)
	fmt.Println(s)
}

Output:

[{Bob 5} {Gopher 13} {Alice 20} {Zac 20} {Vera 24}]

func Values

func Values[Slice ~[]E, E any](s Slice) iter.Seq[E]

Values 返回一个迭代器,按顺序产生切片元素。

Example
package main

import (
	"fmt"
	"slices"
)

func main() {
	names := []string{"Alice", "Bob", "Vera"}
	for v := range slices.Values(names) {
		fmt.Println(v)
	}
}

Output:

Alice
Bob
Vera