# How to Compare Struct, Slice or Map in GO? [SOLVED]

Written By - Tuan Nguyen

In Golang, it is very simple to compare the basic data types: int64, float64, string, and boolean: we just need to use the `==` or `!=` operator. But for the complex data type such as structs, slices, or maps, how can we know if two variables are equal? In today's article, I will show you several methods to determine if two structs, slices, or maps are equal or not. We can use some built-in function or write our code to perform this operation.

## Method 1: Using the DeepEqual() function to compare structs, slices, and maps

`func DeepEqual(x, y any) bool`: DeepEqual reports whether x and y are “deeply equal,” defined as follows. Two values of the identical type are deeply equal if one of the following cases applies. Values of distinct types are never deeply equal:

1. Slice values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array (that is, `&x == &y`) or their corresponding elements (up to length) are deeply equal. Note that a non-nil empty slice and a nil slice (for example, `[]byte{} and []byte(nil)`) are not deeply equal.

2. Struct values are deeply equal if their corresponding fields, both exported and unexported, are deeply equal.

3. Map values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they are the same map object or their corresponding keys (matched using Go equality) map to deeply equal values.

### Compare two structs

The example below shows how to use the `DeepEqual()` function to compare two structs:

``````package main

import (
"fmt"
"reflect"
)

type person struct {
name string
age  int
}

func main() {
person1 := person{"Bob", 20}
person2 := person{"Bob", 20}
person3 := person{"Anna", 20}
fmt.Println("person1 equal person2?:", reflect.DeepEqual(person1, person2))
fmt.Println("person1 equal person3?:", reflect.DeepEqual(person1, person3))
}
``````

Output:

```person1 equal person2?: true
person1 equal person3?: false```

### Compare two slices

The example below shows how to use the `DeepEqual()` function to compare two slices:

``````package main

import (
"fmt"
"reflect"
)

func main() {
slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}
slice3 := []int{1, 2}
fmt.Println("slice1 equal slice2?:", reflect.DeepEqual(slice1, slice2))
fmt.Println("slice1 equal slice3?:", reflect.DeepEqual(slice1, slice3))
}``````

Output:

```slice1 equal slice2?: true
slice1 equal slice3?: false```

### Compare two maps

The example below shows how to use the `DeepEqual()` function to compare two maps:

``````package main

import (
"fmt"
"reflect"
)

func main() {
map1 := map[string]string{
"Anna": "anna@gmail.com",
"Bob":  "bob@gmail.com",
}
map2 := map[string]string{
"Anna": "anna@gmail.com",
"Bob":  "bob@gmail.com",
}
map3 := map[string]string{
"Anna":   "anna@gmail.com",
"Daniel": "daniel@gmail.com",
}
fmt.Println("map1 equal map2?:", reflect.DeepEqual(map1, map2))
fmt.Println("map1 equal map3?:", reflect.DeepEqual(map1, map3))
}
``````

Output:

```map1 equal map2?: true
map1 equal map3?: false```

## Method 2: Write our own function to compare maps, structs, and slices

Depending on what kind of business logic we want, we can define our functions to determine if two structs, maps, and slices are equal or not. The following code shows the basic logic to compare 2 maps and slices:

``````package main

import (
"fmt"
)

func main() {
map1 := map[string]string{
"Anna": "anna@gmail.com",
"Bob":  "bob@gmail.com",
}
map2 := map[string]string{
"Anna": "anna@gmail.com",
"Bob":  "bob@gmail.com",
}

slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}

t1 := T{slice1, map1}
t2 := T{slice2, map2}
fmt.Println("t1 equal t2?:", compare(t1, t2))
}

type T struct {
Z []int
M map[string]string
}

func compare(a, b T) bool {
if &a == &b {
return true
}

if len(a.Z) != len(b.Z) || len(a.M) != len(b.M) {
return false
}

//compare 2 slice
for i, v := range a.Z {
if b.Z[i] != v {
return false
}
}

//compare 2 maps
for k, v := range a.M {
if b.M[k] != v {
return false
}
}
return true
}``````

Output:

`t1 equal t2?: true`

## Method 3: Use some other functions to compare maps, slices, and structs

### Use the `cmp.Equal()` to compare two structs

`func Equal(x, y interface{}, opts ...Option) bool`: Equal reports whether x and y are equal by recursively applying the following rules in the given order to x and y and all of their sub-values.

In this example, we will try to compare 2 structs by using the `cmp.Equal()` and the `cmpopts.IgnoreFields` option which skips comparing some fields in the struct:

``````package main

import (
"fmt"

)

type Person struct {
Name string
Age  int
}

func main() {
person1 := Person{"Bob", 20}
person2 := Person{"Bob", 20}
person3 := Person{"Bob", 40}

fmt.Println("person1 equal person2?:", cmp.Equal(person1, person2))
fmt.Println("person1 equal person3?:", cmp.Equal(person1, person3))
fmt.Println("person1 equal person3 skip age?:", cmp.Equal(person1, person3, cmpopts.IgnoreFields(Person{}, "Age")))
}``````

Output:

```person1 equal person2?: true
person1 equal person3?: false
person1 equal person3 skip age?: true```

Noted that be careful when using this method because it is intended to only be used in tests, as performance is not a goal and it may panic if it cannot compare the values. Its propensity towards panicking means that it's unsuitable for production environments where a spurious panic may be fatal.

### Use == operate to compare one-level structs

If you want to compare simple one-level structs, the best and simple method is using the == operator:

``````package main

import (
"fmt"
)

type Person struct {
Name string
Age  int
}

func main() {
person1 := Person{"Bob", 20}
person2 := Person{"Bob", 20}
person3 := Person{"Bob", 40}

fmt.Println("person1 equal person2?:", person1 == person2)
fmt.Println("person1 equal person3?:", person1 == person3)
}``````

Output:

```person1 equal person2?: true
person1 equal person3?: false```

### Using the maps.Equal() to compare maps; slices.Equal() to compare slices

Go generics have introduced a new function to compare two maps and two slices. First, you need to get some additional packages:

```go get golang.org/x/exp/maps
go get golang.org/x/exp/slices```

Here is an example of using the `Equal()` functions to compare slices and maps:

``````package main

import (
"fmt"

"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
)

func main() {
map1 := map[string]string{
"Anna": "anna@gmail.com",
"Bob":  "bob@gmail.com",
}
map2 := map[string]string{
"Anna": "anna@gmail.com",
"Bob":  "bob2@gmail.com",
}

slice1 := []int{1, 2, 3}
slice2 := []int{1, 2, 3}

fmt.Println("map1 equal map2?:", maps.Equal(map1, map2))
fmt.Println("map1 equal map2?:", slices.Equal(slice1, slice2))
}
``````

Output:

```map1 equal map2?: false
map1 equal map2?: true```

## Summary

In Golang, the `DeepEqual` function is used to compare struct, slice, and map equality. It is used to determine whether or not two items are "deeply equal". Besides this function, we also can use some other functions such as `cmp.Equal()`, `maps.Equal` and `slices.Equal()`. Last but not least, we can also build your own version of the compare function as shown above.

## References

Categories GO

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation. For any other feedbacks or questions you can either use the comments section or contact me form.