Series

Here are all the posts in this series about the slices package.

Introduction

In the last post of this series, I discussed the Compare API from the slices package. In this post, I will share how the Contains, Delete, and Equal APIs work.

Contains

The Contains API reports whether a specified value exists in a specified collection.

Listing 1

01 package main
02
03 import (
04     "fmt"
05     "slices"
06 )
07
08 func main() {
09     list := []int{1, 2, 3, 4, 5, 6}
10     fmt.Println("Slice", list)

Listing 1 starts with creating a collection of integers and then displaying those integers. It just so happens the list is sorted, but this is not a requirement.

Listing 2

12     ​​hasZero := slices.Contains(list, 0)
13     fmt.Println("Does the list contain 0:", hasZero)
14
15     hasFour := slices.Contains(list, 4)
16     fmt.Println("Does the list contain 4:", hasFour)
17 }

Listing 2 performs two calls to the Contains API. The first call looks for a value that does not exist and the second call looks for a value that does exist.

Listing 3

Slice [1 2 3 4 5 6]
Does the list contain 0: false
Does the list contain 4: true

Listing 3 shows the output of running this program. You can see 0 is not found, but the value of 4 is found.

There is a version of the Contains API that allows you to provide a custom compare function.

Listing 4

25 func compare(a int) func(int) bool {
26     return func(b int) bool {
27         return a == b
28     }
29 }

Listing 4 shows a function named compare that returns a compare function that can be used with the ContainsFunc API. It uses closures to accept the value to compare with a value in the collection. The ContainsFunc API will call the returned function for every element in the collection until it is found.

Listing 5

18     hasZero = slices.ContainsFunc(list, compare(0))
19     fmt.Println("Does the list contain 0:", hasZero)
20
21     hasFour = slices.ContainsFunc(list, compare(4))
22     fmt.Println("Does the list contain 4:", hasFour)
23 }

Listing 5 performs two calls to the ContainsFunc API. The two calls and the results are the same as in the example calling the Contains API.

Delete

The Delete API removes a specified contiguous set of elements from a specified collection. The underlying array is modified eliminating the creation a new underlying array.

Listing 6

01 package main
02
03 import (
04     "fmt"
05     "slices"
06 )
07
08 func main() {
09     list := []int{1, 2, 3, 4, 5, 6}
10     fmt.Printf("List: Addr(%x), %v\n", &list[0], list)
11 }

Listing 6 starts the program by constructing and printing a collection of integers.

Listing 7

List: Addr(c00007a000), [1 2 3 4 5 6]

Listing 7 shows the output of the program. Notice the address of the first element since it’s important to see if that changes after a delete operation.

Listing 8

12     list = slices.Delete(list, 1, 2)
13     fmt.Printf("List: Addr(%x), %v\n", &list[0], list)
14 }

Listing 8 calls the Delete API to remove the second element (the number 2) from the collection. The parameters are like a slice operation where [1, 2) or remove elements at index 1 through index 2 not including index 2.

Listing 9

List: Addr(c00007a000), [1 3 4 5 6]

Listing 9 shows the output of the program. Notice the value of 2 has been removed and the address of the underlying array is the same.

Listing 10

15     list = slices.Delete(list, 2, 4)
16     fmt.Printf("List: Addr(%x), %v\n", &list[0], list)
17 }

Listing 10 calls the Delete API to remove the third and fourth elements (the numbers 4 and 5 ) from the collection.

Listing 11

List: Addr(c00007a000), [1 3 6]

Listing 11 shows the output of the program. Notice the values of 4 and 5 have been removed and the address of the underlying array is still the same.

Equal

The Equal API reports whether two collections are equal by comparing the length of each collection and then testing that all the elements are equal.

Listing 12

01 package main
02
03 import (
04     "fmt"
05     "slices"
06 )
07
08 func main() {
09     list1 := []int{1, 2, 3, 4, 5}
10     list2 := []int{1, 2, 6, 4, 5, 6}
11     list3 := []int{1, 2, 3, 4}
12     list4 := []int{1, 2, 3, 4}
13
14     fmt.Println("Slice1", list1)
15     fmt.Println("Slice2", list2)
16     fmt.Println("Slice3", list3)
17     fmt.Println("Slice4", list4)
18 }

Listing 12 starts the program with 4 different integer collections. The third and forth collections are identical.

Listing 13

Slice1 [1 2 3 4 5]
Slice2 [1 2 6 4 5 6]
Slice3 [1 2 3 4]
Slice4 [1 2 3 4]

Listing 13 shows the output of the program. Notice slice 3 and 4 are the same.

Listing 14

19     fmt.Println("list1 == list2", slices.Equal(list1, list2))
20     fmt.Println("list3 == list4", slices.Equal(list3, list4))
21 }

Listing 14 makes calls to the Equal API inside calls to Println. The result of the Equal API is either true or false and the result is passed as a parameter to the Println function. In the first call, the first and second collections are compared and in the second call, the third and fourth collections are compared.

Listing 15

list1 == list2 false
list3 == list4 true

Listing 15 shows the output of the program. You can see the Equal API identifies the first and second collections are not equal, but the third and forth collections are equal.

There is a version of the Equals API that allows you to provide a custom compare function.

Listing 16

26 func compare(a, b int) bool {
27     return a == b
28 }

Listing 16 shows a function named compare that returns a bool depending if the two specified values are equal. When it comes to integers, this check is obvious. When it comes to a more complex type, this function lets you define how the values can be considered equal.

Listing 17

22    fmt.Println("list1 == list2", slices.EqualFunc(list1, list2, compare))
23    fmt.Println("list3 == list4", slices.EqualFunc(list3, list4, compare))
24 }

Listing 17 makes the same calls as in listing 14, but this time uses the EqualFunc API and the custom compare function. The output is identical.

Listing 18

list1 == list2 false
list3 == list4 true

Listing 17 shows the output of the program.

Conclusion

You can see how cool this new slices package is by providing the Contains, Delete, and Equal APIs. In the next post, we will explore the Index, Grow,, and Insert APIs.

If you want to cheat and see all the examples I have prepared for future posts, check out the Go training repo. https://github.com/ardanlabs/gotraining/tree/master/topics/go/packages/slices

Trusted by Top Technology Companies

We've built our reputation as educators and bring that mentality to every project. When you partner with us, your team will learn best practices and grow along the way.

30,000+

Engineers Trained

1,000+

Companies Worldwide

14+

Years in Business