Spec-Zone.ru › Go

Пакет slices

  • import "slices"
  • Обзор
  • Указатель
  • Примеры

Обзор

Пакет slices определяет различные функции, полезные при работе со срезами любого типа.

Указатель

  • func All[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]
  • func AppendSeq[Slice ~[]E, E any](s Slice, seq iter.Seq[E]) Slice
  • func Backward[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]
  • func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)
  • func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)
  • func Chunk[Slice ~[]E, E any](s Slice, n int) iter.Seq[Slice]
  • func Clip[S ~[]E, E any](s S) S
  • func Clone[S ~[]E, E any](s S) S
  • func Collect[E any](seq iter.Seq[E]) []E
  • func Compact[S ~[]E, E comparable](s S) S
  • func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S
  • func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int
  • func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int
  • func Concat[S ~[]E, E any](slices ...S) S
  • func Contains[S ~[]E, E comparable](s S, v E) bool
  • func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool
  • func Delete[S ~[]E, E any](s S, i, j int) S
  • func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S
  • func Equal[S ~[]E, E comparable](s1, s2 S) bool
  • func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool
  • func Grow[S ~[]E, E any](s S, n int) S
  • func Index[S ~[]E, E comparable](s S, v E) int
  • func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int
  • func Insert[S ~[]E, E any](s S, i int, v ...E) S
  • func IsSorted[S ~[]E, E cmp.Ordered](x S) bool
  • func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool
  • func Max[S ~[]E, E cmp.Ordered](x S) E
  • func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E
  • func Min[S ~[]E, E cmp.Ordered](x S) E
  • func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E
  • func Repeat[S ~[]E, E any](x S, count int) S
  • func Replace[S ~[]E, E any](s S, i, j int, v ...E) S
  • func Reverse[S ~[]E, E any](s S)
  • func Sort[S ~[]E, E cmp.Ordered](x S)
  • func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int)
  • func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int)
  • func Sorted[E cmp.Ordered](seq iter.Seq[E]) []E
  • func SortedFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E
  • func SortedStableFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E
  • func Values[Slice ~[]E, E any](s Slice) iter.Seq[E]

Примеры

All
AppendSeq
Backward
BinarySearch
BinarySearchFunc
Chunk
Clip
Clone
Collect
Compact
CompactFunc
Compare
CompareFunc
Concat
Contains
ContainsFunc
Delete
DeleteFunc
Equal
EqualFunc
Grow
Index
IndexFunc
Insert
IsSorted
IsSortedFunc
Max
MaxFunc
Min
MinFunc
Repeat
Replace
Reverse
Sort
SortFunc (CaseInsensitive)
SortFunc (MultiField)
SortStableFunc
Sorted
SortedFunc
SortedStableFunc
Values

Файлы пакета

iter.go slices.go sort.go zsortanyfunc.go zsortordered.go

func All 1.23

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

All возвращает итератор по парам «индекс–значение» среза в обычном порядке.

Пример

Код:

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

Вывод:

0 : Alice
1 : Bob
2 : Vera

func AppendSeq 1.23

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

AppendSeq добавляет значения из seq в срез и возвращает расширенный срез. Если seq пуст, результат сохраняет nil-значение s.

Пример

Код:

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)

Вывод:

[1 2 0 2 4 6 8]

func Backward 1.23

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

Backward возвращает итератор по парам «индекс-значение» в срезе, обходя его в обратном направлении с убывающими индексами.

Пример

Код:

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

Вывод:

2 : Vera
1 : Bob
0 : Alice

func BinarySearch 1.21

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

BinarySearch ищет значение target в отсортированном срезе и возвращает первую позицию, в которой найдено значение target, или позицию, в которой оно располагалось бы в порядке сортировки; также функция возвращает bool, указывающий, действительно ли значение target найдено в срезе. Срез должен быть отсортирован по возрастанию.

Пример

Код:

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)

Вывод:

Vera: 2 true
Bill: 1 false

func BinarySearchFunc 1.21

func BinarySearchFunc[S ~[]E, 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 в срезе.

Пример

Код:

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)

Вывод:

Bob: 1 true

func Chunk 1.23

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

Chunk возвращает итератор по последовательным подсрезам s размером не более n элементов. Все подсрезы, кроме последнего, будут иметь размер n. Ёмкость всех подсрезов ограничена их длиной. Если s пуст, последовательность пуста: в ней нет пустого среза. Chunk вызывает панику, если n меньше 1.

Пример

Код:

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

Вывод:

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

func Clip 1.21

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

Clip удаляет из среза неиспользуемую ёмкость, возвращая s[:len(s):len(s)]. Результат сохраняет nil-значение s.

Пример

Код:

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

Вывод:

10
[0 1 2 3]
4
4

func Clone 1.21

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

Clone возвращает копию среза. Элементы копируются с помощью присваивания, поэтому это поверхностная копия. У результата может быть дополнительная неиспользуемая ёмкость. Результат сохраняет nil-значение s.

Пример

Код:

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

Вывод:

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

func Collect 1.23

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

Collect собирает значения из seq в новый срез и возвращает его. Если seq пуст, результат равен nil.

Пример

Код:

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

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

Вывод:

[0 2 4 6 8]

func Compact 1.21

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

Compact заменяет последовательные группы равных элементов одной копией. Это аналог команды uniq в Unix. Compact изменяет содержимое среза s и возвращает изменённый срез, длина которого может быть меньше. Compact обнуляет элементы между новой и исходной длиной. Результат сохраняет nil-значение s.

Пример

Код:

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

Вывод:

[0 1 2 3 5 8]

func CompactFunc 1.21

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

CompactFunc похожа на Compact, но использует функцию равенства для сравнения элементов. В группах элементов, считающихся равными, CompactFunc оставляет первый элемент. CompactFunc обнуляет элементы между новой и исходной длиной. Результат сохраняет nil-значение s.

Пример

Код:

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

Вывод:

[bob alice Vera]

func Compare 1.21

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

Compare сравнивает элементы s1 и s2, используя cmp.Compare для каждой пары элементов. Элементы сравниваются последовательно, начиная с индекса 0, пока не встретятся два неравных элемента. Возвращается результат сравнения первой пары неравных элементов. Если оба среза равны до конца одного из них, более короткий срез считается меньшим. Результат равен 0, если s1 == s2, -1, если s1 < s2, и +1, если s1 > s2.

Пример

Код:

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

Вывод:

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

func CompareFunc 1.21

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

Пример

Код:

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

func Concat 1.22

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

Concat возвращает новый срез, объединяющий переданные срезы. Если результат объединения пуст, возвращается nil.

Пример

Код:

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

Вывод:

[0 1 2 3 4 5 6]

func Contains 1.21

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

Contains сообщает, присутствует ли v в s.

Пример

Код:

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

Вывод:

true
false

func ContainsFunc 1.21

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

ContainsFunc сообщает, удовлетворяет ли хотя бы один элемент e среза s условию f(e). Функция прекращает работу, как только вызов f возвращает true.

Пример

Код:

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)

Вывод:

Has a negative: true
Has an odd number: false

func Delete 1.21

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

Delete изменяет s на месте, удаляя элементы s[i:j], и возвращает изменённый срез. Delete вызывает панику, если j > len(s) или s[i:j] не является допустимым срезом s. Сложность Delete — O(len(s)-i), поэтому, если нужно удалить много элементов, лучше удалить их все одним вызовом, а не удалять по одному. Delete обнуляет элементы s[len(s)-(j-i):len(s)]. Если результат пуст, он сохраняет nil-значение s.

Пример

Код:

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

Вывод:

[a e]

func DeleteFunc 1.21

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

DeleteFunc изменяет s на месте, удаляя все элементы, для которых del возвращает true, и возвращает изменённый срез. DeleteFunc обнуляет элементы между новой и исходной длиной. Если результат пуст, он имеет такое же значение nil, как s.

Пример

Код:

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)

Результат:

[0 2 8]

func Equal 1.21

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

Equal сообщает, равны ли два среза: имеют ли они одинаковую длину и равны ли все их элементы. Если длины различаются, Equal возвращает false. В противном случае элементы сравниваются в порядке возрастания индексов, и сравнение прекращается при обнаружении первой неравной пары. Пустые и nil-срезы считаются равными. Значения NaN с плавающей точкой не считаются равными.

Пример

Код:

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

Результат:

true
false

func EqualFunc 1.21

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

EqualFunc проверяет, равны ли два среза, применяя функцию сравнения равенства к каждой паре элементов. Если длины различаются, EqualFunc возвращает false. В противном случае элементы сравниваются в порядке возрастания индексов, и сравнение прекращается на первом индексе, для которого eq возвращает false.

Пример

Код:

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

func Grow 1.21

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

Grow при необходимости увеличивает ёмкость среза, гарантируя место ещё для n элементов. После вызова Grow(n) в срез можно добавить не менее n элементов без дополнительного выделения памяти. Если n отрицательно или для выделения памяти требуется слишком большой объём, Grow вызывает панику. Результат сохраняет значение nil среза s.

Пример

Код:

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

Результат:

4
[0 42 -10 8]
4
8

func Index 1.21

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

Index возвращает индекс первого вхождения v в s или -1, если такого элемента нет.

Пример

Код:

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

Результат:

2
-1

func IndexFunc 1.21

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

IndexFunc возвращает первый индекс i, для которого выполняется f(s[i]), или -1, если такого индекса нет.

Пример

Код:

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

func Insert 1.21

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

Insert изменяет s на месте, вставляя значения v... по индексу i, и возвращает изменённый срез. Элементы в s[i:] сдвигаются, освобождая место. В возвращаемом срезе r значение r[i] == v[0], а если i < len(s), то r[i+len(v)] == значение, которое изначально находилось в s[i]. Insert вызывает панику, если i > len(s). Эта функция имеет сложность O(len(s) + len(v)). Если результат пуст, он имеет такое же значение nil, как s.

Пример

Код:

names := []string{"Alice", "Bob", "Vera"}
names = slices.Insert(names, 1, "Bill", "Billie")
names = slices.Insert(names, len(names), "Zac")
fmt.Println(names)

Результат:

[Alice Bill Billie Bob Vera Zac]

func IsSorted 1.21

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

IsSorted сообщает, отсортирован ли x по возрастанию.

Пример

Код:

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

Результат:

true
false

func IsSortedFunc 1.21

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

IsSortedFunc сообщает, отсортирован ли x по возрастанию, используя cmp в качестве функции сравнения, определённой для SortFunc.

Пример

Код:

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

Результат:

true
false

func Max 1.21

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

Max возвращает максимальное значение в x. Если x пуст, функция вызывает панику. Для чисел с плавающей точкой типа E функция Max распространяет NaN (любое значение NaN в x приводит к тому, что результатом становится NaN).

Пример

Код:

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

Результат:

42

func MaxFunc 1.21

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

MaxFunc возвращает максимальное значение в x, используя cmp для сравнения элементов. Если x пуст, функция вызывает панику. Если согласно функции cmp максимальных элементов несколько, MaxFunc возвращает первый из них.

Пример

Код:

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)

Результат:

Alice

func Min 1.21

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

Min возвращает минимальное значение в x. Если x пуст, функция вызывает панику. Для чисел с плавающей точкой Min распространяет NaN (любое значение NaN в x приводит к тому, что результатом становится NaN).

Пример

Код:

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

Результат:

-10

func MinFunc 1.21

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

MinFunc возвращает минимальное значение в x, используя cmp для сравнения элементов. Если x пуст, функция вызывает панику. Если согласно функции cmp минимальных элементов несколько, MinFunc возвращает первый из них.

Пример

Код:

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)

Результат:

Bob

func Repeat 1.23

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

Repeat возвращает новый срез, содержащий указанное число копий переданного среза. Длина и ёмкость результата равны len(x) * count. Результат никогда не бывает nil. Repeat вызывает панику, если count отрицателен или результат вычисления (len(x) * count) переполняется.

Пример

Код:

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

Результат:

[0 1 2 3 0 1 2 3]

func Replace 1.21

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

Replace изменяет s на месте, заменяя элементы s[i:j] на переданные значения v, и возвращает изменённый срез. Replace вызывает панику, если j > len(s) или s[i:j] не является допустимым срезом s. Если len(v) < (j-i), Replace обнуляет элементы между новой и исходной длиной. Если результат пуст, он имеет такое же значение nil, как s.

Пример

Код:

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

Результат:

[Alice Bill Billie Cat Zac]

func Reverse 1.21

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

Reverse меняет порядок элементов среза на обратный на месте.

Пример

Код:

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

Результат:

[VERA Bob alice]

func Sort 1.21

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

Sort сортирует срез значений любого упорядоченного типа по возрастанию. При сортировке чисел с плавающей точкой значения NaN располагаются перед остальными.

Пример

Код:

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

Результат:

[-10 0 8 42]

func SortFunc 1.21

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

SortFunc сортирует срез x по возрастанию в соответствии с функцией cmp. Стабильность этой сортировки не гарантируется. cmp(a, b) должна возвращать отрицательное число, если a < b, положительное число, если a > b, и ноль, если a == b или a и b несравнимы в смысле строгого слабого упорядочения.

Для SortFunc требуется, чтобы cmp задавала строгое слабое упорядочение. См. https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings. Для несравнимых элементов функция должна возвращать 0.

Пример (без учёта регистра)

Код:

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)

Вывод:

[alice Bob VERA]

Пример (несколько полей)

Код:

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)

Вывод:

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

func SortStableFunc 1.21

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

SortStableFunc сортирует срез x, сохраняя исходный порядок равных элементов, используя cmp для сравнения элементов так же, как SortFunc.

Пример

Код:

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)

Вывод:

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

func Sorted 1.23

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

Sorted собирает значения из seq в новый срез, сортирует его и возвращает. Если seq пуст, результатом будет nil.

Пример

Код:

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

Вывод:

[-6 -2 0 4 8]
true

func SortedFunc 1.23

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

SortedFunc собирает значения из seq в новый срез, сортирует его с помощью функции сравнения и возвращает. Если seq пуст, результатом будет nil.

Пример

Код:

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)

Вывод:

[8 4 0 -2 -6]

func SortedStableFunc 1.23

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

SortedStableFunc собирает значения из seq в новый срез. Затем сортирует срез, сохраняя исходный порядок равных элементов и используя функцию сравнения для сравнения элементов. Функция возвращает новый срез. Если seq пуст, результатом будет nil.

Пример

Код:

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)

Вывод:

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

func Values 1.23

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

Values возвращает итератор, выдающий элементы среза по порядку.

Пример

Код:

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

Вывод:

Alice
Bob
Vera

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/slices/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API