Menu
Coddy logo textTech

sort.Interface

Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 74 z 107.

Pakiet sort stanowi kolejny doskonały przykład projektowania opartego na interfejsach. Aby posortować własną kolekcję, Twój typ musi implementować sort.Interface:

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

Te trzy metody dostarczają algorytmowi sortowania wszystkiego, czego potrzebuje: długość kolekcji, sposób porównywania elementów i sposób ich zamiany. Oto jak sprawić, by wycinek własnych struktur można było sortować:

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}]
}

Kluczowe jest utworzenie nazwanego typu (ByAge) na podstawie swojej wycinkowej struktury danych. Dzięki temu możesz zdefiniować różne sposoby sortowania tych samych danych. Możesz utworzyć typ ByName z inną implementacją Less, aby sortować alfabetycznie.

Gdy Twój typ spełnia wymagania interfejsu sort.Interface, automatycznie współpracuje z funkcjami sort.Sort(), sort.Reverse() i sort.IsSorted().

challenge icon

Wyzwanie

Łatwy

Stwórzmy system magazynowy z produktami, które można sortować, demonstrujący możliwości interfejsu Go sort.Interface! Utworzysz typ Product i zaimplementujesz wiele strategii sortowania, dzięki czemu tę samą kolekcję będzie można sortować na różne sposoby.

Rozmieścisz kod w dwóch plikach:

  • product.go: Zdefiniuj typ produktu i implementacje sortowania.

    Utwórz strukturę Product z trzema polami: Name (string), Price (float64) i Quantity (int).

    Utwórz dwa nazwane typy bazujące na []Product:

    • ByPrice — do sortowania produktów według ceny w porządku rosnącym
    • ByQuantity — do sortowania produktów według ilości w porządku malejącym (największa ilość jako pierwsza)

    Każdy typ musi implementować trzy metody wymagane przez sort.Interface: Len(), Less(i, j int) i Swap(i, j int). Metoda Less określa kolejność sortowania dla każdego typu.

  • main.go: Utwórz magazyn produktów i posortuj go.

    Wczytaj tryb sortowania (price lub quantity), a następnie liczbę produktów i ich szczegóły. Każdy produkt jest podany w trzech wierszach: nazwa, cena i ilość.

    Utwórz wycinek produktów, posortuj go za pomocą odpowiedniego typu sortowania w zależności od trybu, a następnie wypisz każdy produkt w następującym formacie:

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

    Wyświetlaj ceny z dwoma miejscami po przecinku.

Dane wejściowe będą następujące:

  • Wiersz 1: Tryb sortowania (price lub quantity)
  • Wiersz 2: Liczba produktów
  • Kolejne wiersze: Szczegóły produktów (nazwa, cena, ilość — trzy wiersze na produkt)

Na przykład dla danych wejściowych:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Wynik powinien być następujący:

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

A dla danych wejściowych:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Wynik powinien być następujący:

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

Zwróć uwagę, że te same dane produktów można sortować na różne sposoby, używając po prostu innego nazwanego typu. Gdy Twoje typy spełniają wymagania sort.Interface, bezproblemowo współpracują z sort.Sort() z biblioteki standardowej.

Spróbuj swoich sił

package main

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

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

	// Wczytaj tryb sortowania
	var mode string
	fmt.Fscanln(reader, &mode)

	// Wczytaj liczbę produktów
	var count int
	fmt.Fscanln(reader, &count)

	// Wczytaj produkty
	products := make([]Product, count)
	for i := 0; i < count; i++ {
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		priceStr, _ := reader.ReadString('\n')
		priceStr = strings.TrimSpace(priceStr)
		price, _ := strconv.ParseFloat(priceStr, 64)

		qtyStr, _ := reader.ReadString('\n')
		qtyStr = strings.TrimSpace(qtyStr)
		quantity, _ := strconv.Atoi(qtyStr)

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

	// TODO: Posortuj produkty według trybu
	// Jeśli mode ma wartość "price", użyj typu ByPrice
	// Jeśli mode ma wartość "quantity", użyj typu ByQuantity
	// Użyj sort.Sort() z odpowiednim typem

	// TODO: Wyświetl każdy produkt w formacie:
	// [Name]: $[Price] (x[Quantity])
	// Użyj fmt.Printf z %.2f do formatowania ceny
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Go online