GoLang Sort Slice of Structs

  1. GoLang Sort Slice of Structs
  2. Sort Slice of Structs by a Field
  3. Sort Slice of Structs by Multiple Fields
GoLang Sort Slice of Structs

This tutorial demonstrates how to sort the slice of structs in GoLang.

GoLang Sort Slice of Structs

GoLang provides two methods to sort a slice of structs; one is sort.Slice, and the other is sort.SliceStable. We also need to use a less function along with these two methods to sort a slice of structs.

The syntax for these methods are:

//sort.Slice
func Slice(x StructSlice, less func(i, j int) bool)

//sort.SliceStable
func Slice(x StructSlice, less func(i, j int) bool)

Where x is the slice of structs, the slice will be sorted based on the less function. Let’s try implementing a few examples to understand how to sort slices of structs in GoLang.

Sort Slice of Structs by a Field

Sorting a slice of structs by a field is the basic example for sorting a slice of structs. Where we compare a value of a member of a struct slice with the other member of the same struct slice based on the field, let’s see an example.

package main

import (
    "fmt"
    "sort"
)

type Employee struct {
    Name   string
    Salary int
}

func main() {
    // Sort in Ascending order
    employees := []Employee{
        {Name: "John", Salary: 1500},
        {Name: "Joe", Salary: 3000},
        {Name: "Jack", Salary: 3400},
    }

    sort.Slice(employees, func(i, j int) bool {
        return employees[i].Salary < employees[j].Salary
    })

    fmt.Println(employees)

    // Sort in Descending order
    employees1 := []Employee{
        {Name: "John", Salary: 1500},
        {Name: "Joe", Salary: 3000},
        {Name: "Jack", Salary: 3400},
    }

    sort.Slice(employees1, func(i, j int) bool {
        return employees1[i].Salary > employees1[j].Salary
    })

    fmt.Println(employees1)
}

The code above contains a struct Employee which have two fields Name and Salary, then it creates a slice of struct and sorts it to ascending order based on the field Salary by using the Slice method and then sort another slice into descending order.

See the output:

[{John 1500} {Joe 3000} {Jack 3400}]
[{Jack 3400} {Joe 3000} {John 1500}]

Now we cannot use the sort.SliceStable on these types of slices, which include key-value pairs (maps) of the filed name and value. With sort.SliceStable, we can sort simple slice of structs which contains only values.

package main

import (
    "fmt"
    "sort"
)

type Employee struct {
    Name   string
    Salary int
}

func main() {
    // Sort in Ascending order
    employees := []Employee{
        {"John", 1500},
        {"Joe", 3000},
        {"Jack", 3400},
    }

    sort.SliceStable(employees, func(i, j int) bool {
        return employees[i].Salary < employees[j].Salary
    })

    fmt.Println(employees)

    // Sort in Descending order
    employees1 := []Employee{
        {"John", 1500},
        {"Joe", 3000},
        {"Jack", 3400},
    }

    sort.SliceStable(employees1, func(i, j int) bool {
        return employees1[i].Salary > employees1[j].Salary
    })

    fmt.Println(employees1)
}

The code above will similarly sort the slice of structs based on a field without the key-value pairs of names and values in the slice of structs.

See the output:

[{John 1500} {Joe 3000} {Jack 3400}]
[{Jack 3400} {Joe 3000} {John 1500}]

Sort Slice of Structs by Multiple Fields

Sorting a slice of structs by multiple fields is also possible. We have to extend the less function; let’s try an example.

package main

import (
    "fmt"
    "sort"
)

type Employee struct {
    Name     string
    Position string
}

func main() {
    // Sort in Descending order
    employees := []Employee{
        {"Michael", "Developer"},
        {"Jack", "Manager"},
        {"Joe", "CEO"},
        {"Leonard", "Intern"},
        {"Sheldon", "Developer"},
    }

    sort.SliceStable(employees, func(i, j int) bool {
        if employees[i].Position != employees[j].Position {
            return employees[i].Position < employees[j].Position
        }

        return employees[i].Name < employees[j].Name
    })

    fmt.Println(employees)

    // Sort in Ascending order
    employees1 := []Employee{
        {"Michael", "Developer"},
        {"Jack", "Manager"},
        {"Joe", "CEO"},
        {"Leonard", "Intern"},
        {"Sheldon", "Developer"},
    }

    sort.SliceStable(employees1, func(i, j int) bool {
        if employees1[i].Position != employees1[j].Position {
            return employees1[i].Position > employees1[j].Position
        }

        return employees1[i].Name > employees1[j].Name
    })

    fmt.Println(employees1)
}

The code above will sort based on both Name and Position, where if the position for two employees is the same, that will be sorted according to the Name field. The slice of the struct will be sorted in descending and ascending order.

See the output:

[{Joe CEO} {Michael Developer} {Sheldon Developer} {Leonard Intern} {Jack Manager}]
[{Jack Manager} {Leonard Intern} {Sheldon Developer} {Michael Developer} {Joe CEO}]
Author: Sheeraz Gul
Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook

Related Article - Go Slice

  • Delete an Element From a Slice in Golang
  • Golang Copy Slice
  • Difference Between []String and ...String in Go
  • Check if a Slice Contains an Element in Golang
  • Create an Empty Slice in Go
  • Related Article - Go Struct

  • Convert Go Struct to JSON
  • Print Struct Variables in Console in Go
  • Get the String Representation of a Struct in Go
  • Golang Array of Structs