Пакет slices
Обзор
Пакет slices определяет различные функции, полезные при работе со срезами любого типа.
Индекс
Примеры
- BinarySearch
- BinarySearchFunc
- Chunk
- Clip
- Clone
- 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 (Регистронезависимая сортировка)
- SortFunc (Сортировка по нескольким полям)
- SortStableFunc
Файлы пакета
iter.go slices.go sort.go zsortanyfunc.go zsortordered.go
func All
func All[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]
All возвращает итератор по парам индекс-значение в срезе в обычном порядке.
func AppendSeq
func AppendSeq[Slice ~[]E, E any](s Slice, seq iter.Seq[E]) Slice
AppendSeq добавляет значения из seq в срез и возвращает расширенный срез.
func Backward
func Backward[Slice ~[]E, E any](s Slice) iter.Seq2[int, E]
Backward возвращает итератор по парам индекс-значение в срезе, проходя по нему в обратном порядке с убывающими индексами.
func BinarySearch
func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool)
BinarySearch ищет target в отсортированном срезе и возвращает самую раннюю позицию, где найден target, или позицию, где target бы появился в порядке сортировки; также возвращает булево значение, указывающее, действительно ли 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
func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool)
BinarySearchFunc работает как BinarySearch, но использует пользовательскую функцию сравнения. Срез должен быть отсортирован по возрастанию, где «возрастание» определяется функцией cmp. cmp должна возвращать 0, если элемент среза соответствует target, отрицательное число, если элемент среза предшествует target, или положительное число, если элемент среза следует за target. 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
func Chunk[Slice ~[]E, E any](s Slice, n int) iter.Seq[Slice]
Chunk возвращает итератор по последовательным под-срезам до n элементов из s. Все, кроме последнего под-срезов, будут иметь размер 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
func Clip[S ~[]E, E any](s S) S
Clip удаляет неиспользуемую ёмкость из среза, возвращая s[:len(s):len(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
func Clone[S ~[]E, E any](s S) S
Clone возвращает копию среза. Элементы копируются с помощью присваивания, поэтому это неглубокая копия. Результат может иметь дополнительную неиспользуемую ёмкость.
Пример
Код:
numbers := []int{0, 42, -10, 8}
clone := slices.Clone(numbers)
fmt.Println(clone)
clone[2] = 10
fmt.Println(numbers)
Вывод:
[0 42 -10 8] [0 42 -10 8]
func Collect
func Collect[E any](seq iter.Seq[E]) []E
Collect собирает значения из seq в новый срез и возвращает его.
func Compact
func Compact[S ~[]E, E comparable](s S) S
Compact заменяет последовательные серии одинаковых элементов одной копией. Это похоже на команду uniq, используемую в Unix. Compact изменяет содержимое среза s и возвращает изменённый срез, который может иметь меньшую длину. Compact обнуляет элементы между новой длиной и исходной длиной.
Пример
Код:
seq := []int{0, 1, 1, 2, 3, 5, 8}
seq = slices.Compact(seq)
fmt.Println(seq)
Вывод:
[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 обнуляет элементы между новой длиной и исходной длиной.
Пример
Код:
names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
names = slices.CompactFunc(names, strings.EqualFold)
fmt.Println(names)
Вывод:
[bob alice Vera]
func Compare
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
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
func Concat[S ~[]E, E any](slices ...S) S
Concat возвращает новый срез, конкатенирующий переданные срезы.
Пример
Код:
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
func Contains[S ~[]E, E comparable](s S, v E) bool
Содержит отчет о том, присутствует ли v в s.
Пример
Код:
numbers := []int{0, 1, 2, 3}
fmt.Println(slices.Contains(numbers, 2))
fmt.Println(slices.Contains(numbers, 4))
Вывод:
true false
func ContainsFunc
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool
ContainsFunc проверяет, существует ли хотя бы один элемент e из s, удовлетворяющий f(e).
Пример
Код:
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
func Delete[S ~[]E, E any](s S, i, j int) S
Delete удаляет элементы s[i:j] из s, возвращая изменённый срез. Delete вызывает панику, если j > len(s) или s[i:j] не является допустимым срезом s. Delete имеет сложность O(len(s)-i), поэтому, если необходимо удалить много элементов, лучше сделать один вызов, удаляющий все элементы вместе, чем удалять их по одному. Delete обнуляет элементы s[len(s)-(j-i):len(s)].
Пример
Код:
letters := []string{"a", "b", "c", "d", "e"}
letters = slices.Delete(letters, 1, 4)
fmt.Println(letters)
Вывод:
[a e]
func DeleteFunc
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S
DeleteFunc удаляет из s все элементы, для которых del возвращает true, возвращая изменённый срез. DeleteFunc обнуляет элементы между новой длиной и исходной длиной.
Пример
Код:
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
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
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
func Grow[S ~[]E, E any](s S, n int) S
Grow увеличивает ёмкость среза, если необходимо, чтобы гарантировать место для ещё n элементов. После Grow(n), как минимум n элементов можно добавить в срез без новой аллокации. Если n отрицательно или слишком велико для выделения памяти, Grow вызывает панику.
Пример
Код:
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
func Index[S ~[]E, E comparable](s S, v E) int
Index возвращает индекс первого вхождения v в s, или -1, если v отсутствует.
Пример
Код:
numbers := []int{0, 42, 8}
fmt.Println(slices.Index(numbers, 8))
fmt.Println(slices.Index(numbers, 7))
Вывод:
2 -1
func IndexFunc
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
func Insert[S ~[]E, E any](s S, i int, v ...E) S
Insert вставляет значения v... в s по индексу i, возвращая изменённый срез. Элементы в s[i:] смещаются вверх, чтобы освободить место. В возвращённом срезе r, r[i] == v[0], и r[i+len(v)] == значение, первоначально находящееся в r[i]. Insert вызывает панику, если i выходит за пределы диапазона. Эта функция имеет сложность O(len(s) + len(v)).
Пример
Код:
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
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
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
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
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
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
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
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
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S
Replace заменяет элементы s[i:j] на заданные v и возвращает изменённый срез. Replace вызывает панику, если j > len(s) или s[i:j] не является допустимым срезом s. Когда len(v) < (j-i), Replace обнуляет элементы между новой длиной и исходной длиной.
Пример
Код:
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
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
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
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
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 Alices 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
func Sorted[E cmp.Ordered](seq iter.Seq[E]) []E
Sorted собирает значения из seq в новый срез, сортирует срез и возвращает его.
func SortedFunc
func SortedFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E
SortedFunc собирает значения из seq в новый срез, сортирует срез, используя функцию сравнения, и возвращает его.
func SortedStableFunc
func SortedStableFunc[E any](seq iter.Seq[E], cmp func(E, E) int) []E
SortedStableFunc собирает значения из seq в новый срез. Затем сортирует срез, сохраняя исходный порядок равных элементов, используя функцию сравнения для сравнения элементов. Возвращает новый срез.
func Values
func Values[Slice ~[]E, E any](s Slice) iter.Seq[E]
Values возвращает итератор, который последовательно возвращает элементы среза в порядке.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/slices/