Menu
Coddy logo textTech

sort.Interface

Part of the Object Oriented Programming section of Coddy's GO journey — lesson 74 of 107.

The sort package provides another excellent example of interface-based design. To sort a custom collection, your type must implement the sort.Interface:

type Interface interface {
    Len() int
    Less(i, j int) bool
    Swap(i, j int)
}

These three methods give the sort algorithm everything it needs: the collection's length, a way to compare elements, and a way to swap them. Here's how to make a slice of custom structs sortable:

type Person struct {
    Name string
    Age  int
}

type ByAge []Person

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

func main() {
    people := []Person{
        {"Alice", 30},
        {"Bob", 25},
        {"Carol", 35},
    }
    
    sort.Sort(ByAge(people))
    fmt.Println(people)
    // [{Bob 25} {Alice 30} {Carol 35}]
}

The key insight is creating a named type (ByAge) based on your slice. This lets you define different sorting behaviors for the same data. You could create ByName with a different Less implementation to sort alphabetically instead.

Once your type satisfies sort.Interface, it works with sort.Sort(), sort.Reverse(), and sort.IsSorted() automatically.

challenge icon

Challenge

Easy

Let's build a sortable product inventory system that demonstrates the power of Go's sort.Interface! You'll create a Product type and implement multiple sorting strategies, allowing the same collection to be sorted in different ways.

You'll organize your code across two files:

  • product.go: Define your product type and sorting implementations.

    Create a Product struct with three fields: Name (string), Price (float64), and Quantity (int).

    Create two named types based on []Product:

    • ByPrice - for sorting products by price in ascending order
    • ByQuantity - for sorting products by quantity in descending order (highest quantity first)

    Each type needs to implement the three methods required by sort.Interface: Len(), Less(i, j int), and Swap(i, j int). The Less method determines the sort order for each type.

  • main.go: Build and sort your product inventory.

    Read a sort mode (price or quantity), then read a count followed by product details. Each product is provided as three lines: name, price, and quantity.

    Create a slice of products, sort them using the appropriate sorting type based on the mode, then print each product in this format:

    [Name]: $[Price] (x[Quantity])

    Display prices with two decimal places.

The following inputs will be provided:

  • Line 1: Sort mode (price or quantity)
  • Line 2: Number of products
  • Following lines: Product details (name, price, quantity - three lines per product)

For example, given:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Your output should be:

Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)

And given:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Your output should be:

Mouse: $29.99 (x50)
Keyboard: $79.99 (x25)
Laptop: $999.99 (x5)

Notice how the same product data can be sorted differently by simply using a different named type. Once your types satisfy sort.Interface, they work seamlessly with sort.Sort() from the standard library.

Try it yourself

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Read sort mode
	var mode string
	fmt.Fscanln(reader, &mode)

	// Read number of products
	var count int
	fmt.Fscanln(reader, &count)

	// Read products
	products := make([]Product, count)
	for i := 0; i < count; i++ {
		name, _ := reader.ReadString('\n')
		name = name[:len(name)-1] // Remove newline

		priceStr, _ := reader.ReadString('\n')
		priceStr = priceStr[:len(priceStr)-1]
		price, _ := strconv.ParseFloat(priceStr, 64)

		qtyStr, _ := reader.ReadString('\n')
		qtyStr = qtyStr[:len(qtyStr)-1]
		quantity, _ := strconv.Atoi(qtyStr)

		products[i] = Product{Name: name, Price: price, Quantity: quantity}
	}

	// TODO: Sort products based on mode
	// If mode is "price", use ByPrice type
	// If mode is "quantity", use ByQuantity type
	// Use sort.Sort() with the appropriate type

	// TODO: Print each product in the format:
	// [Name]: $[Price] (x[Quantity])
	// Use fmt.Printf with %.2f for price formatting
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming