1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package slices_test
6
7import (
8	"cmp"
9	"fmt"
10	"slices"
11	"strconv"
12	"strings"
13)
14
15func ExampleBinarySearch() {
16	names := []string{"Alice", "Bob", "Vera"}
17	n, found := slices.BinarySearch(names, "Vera")
18	fmt.Println("Vera:", n, found)
19	n, found = slices.BinarySearch(names, "Bill")
20	fmt.Println("Bill:", n, found)
21	// Output:
22	// Vera: 2 true
23	// Bill: 1 false
24}
25
26func ExampleBinarySearchFunc() {
27	type Person struct {
28		Name string
29		Age  int
30	}
31	people := []Person{
32		{"Alice", 55},
33		{"Bob", 24},
34		{"Gopher", 13},
35	}
36	n, found := slices.BinarySearchFunc(people, Person{"Bob", 0}, func(a, b Person) int {
37		return strings.Compare(a.Name, b.Name)
38	})
39	fmt.Println("Bob:", n, found)
40	// Output:
41	// Bob: 1 true
42}
43
44func ExampleCompact() {
45	seq := []int{0, 1, 1, 2, 3, 5, 8}
46	seq = slices.Compact(seq)
47	fmt.Println(seq)
48	// Output:
49	// [0 1 2 3 5 8]
50}
51
52func ExampleCompactFunc() {
53	names := []string{"bob", "Bob", "alice", "Vera", "VERA"}
54	names = slices.CompactFunc(names, strings.EqualFold)
55	fmt.Println(names)
56	// Output:
57	// [bob alice Vera]
58}
59
60func ExampleCompare() {
61	names := []string{"Alice", "Bob", "Vera"}
62	fmt.Println("Equal:", slices.Compare(names, []string{"Alice", "Bob", "Vera"}))
63	fmt.Println("V < X:", slices.Compare(names, []string{"Alice", "Bob", "Xena"}))
64	fmt.Println("V > C:", slices.Compare(names, []string{"Alice", "Bob", "Cat"}))
65	fmt.Println("3 > 2:", slices.Compare(names, []string{"Alice", "Bob"}))
66	// Output:
67	// Equal: 0
68	// V < X: -1
69	// V > C: 1
70	// 3 > 2: 1
71}
72
73func ExampleCompareFunc() {
74	numbers := []int{0, 43, 8}
75	strings := []string{"0", "0", "8"}
76	result := slices.CompareFunc(numbers, strings, func(n int, s string) int {
77		sn, err := strconv.Atoi(s)
78		if err != nil {
79			return 1
80		}
81		return cmp.Compare(n, sn)
82	})
83	fmt.Println(result)
84	// Output:
85	// 1
86}
87
88func ExampleContainsFunc() {
89	numbers := []int{0, 42, -10, 8}
90	hasNegative := slices.ContainsFunc(numbers, func(n int) bool {
91		return n < 0
92	})
93	fmt.Println("Has a negative:", hasNegative)
94	hasOdd := slices.ContainsFunc(numbers, func(n int) bool {
95		return n%2 != 0
96	})
97	fmt.Println("Has an odd number:", hasOdd)
98	// Output:
99	// Has a negative: true
100	// Has an odd number: false
101}
102
103func ExampleDelete() {
104	letters := []string{"a", "b", "c", "d", "e"}
105	letters = slices.Delete(letters, 1, 4)
106	fmt.Println(letters)
107	// Output:
108	// [a e]
109}
110
111func ExampleDeleteFunc() {
112	seq := []int{0, 1, 1, 2, 3, 5, 8}
113	seq = slices.DeleteFunc(seq, func(n int) bool {
114		return n%2 != 0 // delete the odd numbers
115	})
116	fmt.Println(seq)
117	// Output:
118	// [0 2 8]
119}
120
121func ExampleEqual() {
122	numbers := []int{0, 42, 8}
123	fmt.Println(slices.Equal(numbers, []int{0, 42, 8}))
124	fmt.Println(slices.Equal(numbers, []int{10}))
125	// Output:
126	// true
127	// false
128}
129
130func ExampleEqualFunc() {
131	numbers := []int{0, 42, 8}
132	strings := []string{"000", "42", "0o10"}
133	equal := slices.EqualFunc(numbers, strings, func(n int, s string) bool {
134		sn, err := strconv.ParseInt(s, 0, 64)
135		if err != nil {
136			return false
137		}
138		return n == int(sn)
139	})
140	fmt.Println(equal)
141	// Output:
142	// true
143}
144
145func ExampleIndex() {
146	numbers := []int{0, 42, 8}
147	fmt.Println(slices.Index(numbers, 8))
148	fmt.Println(slices.Index(numbers, 7))
149	// Output:
150	// 2
151	// -1
152}
153
154func ExampleIndexFunc() {
155	numbers := []int{0, 42, -10, 8}
156	i := slices.IndexFunc(numbers, func(n int) bool {
157		return n < 0
158	})
159	fmt.Println("First negative at index", i)
160	// Output:
161	// First negative at index 2
162}
163
164func ExampleInsert() {
165	names := []string{"Alice", "Bob", "Vera"}
166	names = slices.Insert(names, 1, "Bill", "Billie")
167	names = slices.Insert(names, len(names), "Zac")
168	fmt.Println(names)
169	// Output:
170	// [Alice Bill Billie Bob Vera Zac]
171}
172
173func ExampleIsSorted() {
174	fmt.Println(slices.IsSorted([]string{"Alice", "Bob", "Vera"}))
175	fmt.Println(slices.IsSorted([]int{0, 2, 1}))
176	// Output:
177	// true
178	// false
179}
180
181func ExampleIsSortedFunc() {
182	names := []string{"alice", "Bob", "VERA"}
183	isSortedInsensitive := slices.IsSortedFunc(names, func(a, b string) int {
184		return strings.Compare(strings.ToLower(a), strings.ToLower(b))
185	})
186	fmt.Println(isSortedInsensitive)
187	fmt.Println(slices.IsSorted(names))
188	// Output:
189	// true
190	// false
191}
192
193func ExampleMax() {
194	numbers := []int{0, 42, -10, 8}
195	fmt.Println(slices.Max(numbers))
196	// Output:
197	// 42
198}
199
200func ExampleMaxFunc() {
201	type Person struct {
202		Name string
203		Age  int
204	}
205	people := []Person{
206		{"Gopher", 13},
207		{"Alice", 55},
208		{"Vera", 24},
209		{"Bob", 55},
210	}
211	firstOldest := slices.MaxFunc(people, func(a, b Person) int {
212		return cmp.Compare(a.Age, b.Age)
213	})
214	fmt.Println(firstOldest.Name)
215	// Output:
216	// Alice
217}
218
219func ExampleMin() {
220	numbers := []int{0, 42, -10, 8}
221	fmt.Println(slices.Min(numbers))
222	// Output:
223	// -10
224}
225
226func ExampleMinFunc() {
227	type Person struct {
228		Name string
229		Age  int
230	}
231	people := []Person{
232		{"Gopher", 13},
233		{"Bob", 5},
234		{"Vera", 24},
235		{"Bill", 5},
236	}
237	firstYoungest := slices.MinFunc(people, func(a, b Person) int {
238		return cmp.Compare(a.Age, b.Age)
239	})
240	fmt.Println(firstYoungest.Name)
241	// Output:
242	// Bob
243}
244
245func ExampleReplace() {
246	names := []string{"Alice", "Bob", "Vera", "Zac"}
247	names = slices.Replace(names, 1, 3, "Bill", "Billie", "Cat")
248	fmt.Println(names)
249	// Output:
250	// [Alice Bill Billie Cat Zac]
251}
252
253func ExampleReverse() {
254	names := []string{"alice", "Bob", "VERA"}
255	slices.Reverse(names)
256	fmt.Println(names)
257	// Output:
258	// [VERA Bob alice]
259}
260
261func ExampleSort() {
262	smallInts := []int8{0, 42, -10, 8}
263	slices.Sort(smallInts)
264	fmt.Println(smallInts)
265	// Output:
266	// [-10 0 8 42]
267}
268
269func ExampleSortFunc_caseInsensitive() {
270	names := []string{"Bob", "alice", "VERA"}
271	slices.SortFunc(names, func(a, b string) int {
272		return strings.Compare(strings.ToLower(a), strings.ToLower(b))
273	})
274	fmt.Println(names)
275	// Output:
276	// [alice Bob VERA]
277}
278
279func ExampleSortFunc_multiField() {
280	type Person struct {
281		Name string
282		Age  int
283	}
284	people := []Person{
285		{"Gopher", 13},
286		{"Alice", 55},
287		{"Bob", 24},
288		{"Alice", 20},
289	}
290	slices.SortFunc(people, func(a, b Person) int {
291		if n := strings.Compare(a.Name, b.Name); n != 0 {
292			return n
293		}
294		// If names are equal, order by age
295		return cmp.Compare(a.Age, b.Age)
296	})
297	fmt.Println(people)
298	// Output:
299	// [{Alice 20} {Alice 55} {Bob 24} {Gopher 13}]
300}
301
302func ExampleSortStableFunc() {
303	type Person struct {
304		Name string
305		Age  int
306	}
307	people := []Person{
308		{"Gopher", 13},
309		{"Alice", 20},
310		{"Bob", 24},
311		{"Alice", 55},
312	}
313	// Stable sort by name, keeping age ordering of Alices intact
314	slices.SortStableFunc(people, func(a, b Person) int {
315		return strings.Compare(a.Name, b.Name)
316	})
317	fmt.Println(people)
318	// Output:
319	// [{Alice 20} {Alice 55} {Bob 24} {Gopher 13}]
320}
321
322func ExampleClone() {
323	numbers := []int{0, 42, -10, 8}
324	clone := slices.Clone(numbers)
325	fmt.Println(clone)
326	clone[2] = 10
327	fmt.Println(numbers)
328	// Output:
329	// [0 42 -10 8]
330	// [0 42 -10 8]
331}
332
333func ExampleGrow() {
334	numbers := []int{0, 42, -10, 8}
335	grow := slices.Grow(numbers, 2)
336	fmt.Println(cap(numbers))
337	fmt.Println(grow)
338	fmt.Println(len(grow))
339	fmt.Println(cap(grow))
340	// Output:
341	// 4
342	// [0 42 -10 8]
343	// 4
344	// 8
345}
346
347func ExampleClip() {
348	a := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
349	s := a[:4:10]
350	clip := slices.Clip(s)
351	fmt.Println(cap(s))
352	fmt.Println(clip)
353	fmt.Println(len(clip))
354	fmt.Println(cap(clip))
355	// Output:
356	// 10
357	// [0 1 2 3]
358	// 4
359	// 4
360}
361
362func ExampleConcat() {
363	s1 := []int{0, 1, 2, 3}
364	s2 := []int{4, 5, 6}
365	concat := slices.Concat(s1, s2)
366	fmt.Println(concat)
367	// Output:
368	// [0 1 2 3 4 5 6]
369}
370
371func ExampleContains() {
372	numbers := []int{0, 1, 2, 3}
373	fmt.Println(slices.Contains(numbers, 2))
374	fmt.Println(slices.Contains(numbers, 4))
375	// Output:
376	// true
377	// false
378}
379
380func ExampleRepeat() {
381	numbers := []int{0, 1, 2, 3}
382	repeat := slices.Repeat(numbers, 2)
383	fmt.Println(repeat)
384	// Output:
385	// [0 1 2 3 0 1 2 3]
386}
387
388func ExampleChunk() {
389	type Person struct {
390		Name string
391		Age  int
392	}
393
394	type People []Person
395
396	people := People{
397		{"Gopher", 13},
398		{"Alice", 20},
399		{"Bob", 5},
400		{"Vera", 24},
401		{"Zac", 15},
402	}
403
404	// Chunk people into []Person 2 elements at a time.
405	for c := range slices.Chunk(people, 2) {
406		fmt.Println(c)
407	}
408
409	// Output:
410	// [{Gopher 13} {Alice 20}]
411	// [{Bob 5} {Vera 24}]
412	// [{Zac 15}]
413}
414