Custom Sorting in Go

Topic Overview

Welcome to Custom Sorting in Go. In this lesson, we'll explore how to use slices and the sort package in Go to organize data structures with custom sorting mechanisms. By applying custom sorting functions, we can enhance data organization and access, dictating the order of elements in our collections.

Quick Recap on Sorting Collections

Sorting collections involves arranging elements in a particular order, making operations like searching within a range more efficient. In Go, while a map doesn't maintain order, sorting can be achieved by extracting keys into a slice and using the sort package:

package main

import (
    "fmt"
    "sort"
)

func main() {
    m := map[string]int{"a": 1, "c": 3, "b": 2}
    keys := make([]string, 0, len(m))
    
    for k := range m {
        keys = append(keys, k)
    }

    sort.Strings(keys)
    
    for _, k := range keys {
        fmt.Printf("%s=%d\n", k, m[k]) // Outputs "a=1", "b=2", "c=3"
    }
}

Introduction to Structs in Go

Structs in Go allow us to create complex data types that encapsulate multiple properties, suitable for representing entities like a Person or a Book. Structs serve as blueprints for creating instances with specific data.

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    person := Person{Name: "John Doe", Age: 30}
    fmt.Println(person.Name) // Outputs "John Doe"
    fmt.Println(person.Age)  // Outputs 30
}

Using Structs and Slices for Custom Sorting

Using structs along with slices allows us to organize complex data. Consider using structs with slices in lieu of data structures that require sorted keys:

package main

import (
    "fmt"
    "sort"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"John", 30},
        {"Alice", 25},
    }

    sort.Slice(people, func(i, j int) bool {
        if people[i].Age != people[j].Age {
            return people[i].Age < people[j].Age
        }
        return people[i].Name < people[j].Name
    })

    for _, person := range people {
        fmt.Printf("%s is %d years old\n", person.Name, person.Age)
    }
    // Output:
    // Alice is 25 years old
    // John is 30 years old
}

In this example, we create a Person struct and sort a slice of Person using custom criteria defined in a sort.Slice function. We define custom sorting criteria using a lambda function, which allows us to specify the logic for determining the order of the elements. The lambda function is passed as an argument to the sort.Slice function, where it takes two indices, i and j, and returns true if the element at index i should appear before the element at index j. This flexibility lets us sort the Person slice first by Age and then by Name if the ages are equal.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal