Menu
Coddy logo textTech

sort.Interface

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 74 von 107.

Das Paket sort bietet ein weiteres hervorragendes Beispiel für schnittstellenbasiertes Design. Um eine benutzerdefinierte Sammlung zu sortieren, muss dein Typ sort.Interface implementieren:

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

Diese drei Methoden liefern dem Sortieralgorithmus alles, was er benötigt: die Länge der collection, eine Möglichkeit, elements zu vergleichen, und eine Möglichkeit, sie zu vertauschen. So machst du einen Slice aus benutzerdefinierten Structs sortierbar:

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

Die entscheidende Erkenntnis besteht darin, einen benannten Typ (ByAge) auf Grundlage deines Slices zu erstellen. Dadurch kannst du für dieselben Daten unterschiedliche Sortierverhalten definieren. Du könntest stattdessen ByName mit einer anderen Implementierung von Less erstellen, um alphabetisch zu sortieren.

Sobald dein Typ sort.Interface erfüllt, funktioniert er automatisch mit sort.Sort(), sort.Reverse() und sort.IsSorted().

challenge icon

Aufgabe

Einfach

Lass uns ein sortierbares Produktinventarsystem erstellen, das die Leistungsfähigkeit von Gos sort.Interface demonstriert! Du erstellst einen Product-Typ und implementierst mehrere Sortierstrategien, sodass dieselbe Sammlung auf unterschiedliche Weise sortiert werden kann.

Du organisierst deinen Code über zwei Dateien:

  • product.go: Definiere deinen Produkttyp und die Sortierimplementierungen.

    Erstelle eine Product-Struktur mit drei Feldern: Name (string), Price (float64) und Quantity (int).

    Erstelle zwei benannte Typen basierend auf []Product:

    • ByPrice – zum Sortieren von Produkten nach dem Preis in aufsteigender Reihenfolge
    • ByQuantity – zum Sortieren von Produkten nach der Menge in absteigender Reihenfolge (höchste Menge zuerst)

    Jeder Typ muss die drei von sort.Interface benötigten Methoden implementieren: Len(), Less(i, j int) und Swap(i, j int). Die Methode Less bestimmt die Sortierreihenfolge für den jeweiligen Typ.

  • main.go: Erstelle und sortiere dein Produktinventar.

    Lies einen Sortiermodus (price oder quantity) und anschließend eine Anzahl gefolgt von den Produktdetails ein. Jedes Produkt wird als drei Zeilen angegeben: Name, Preis und Menge.

    Erstelle ein Slice mit Produkten, sortiere es mithilfe des passenden Sortiertyps abhängig vom Modus und gib anschließend jedes Produkt in diesem Format aus:

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

    Gib Preise mit zwei Dezimalstellen aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Sortiermodus (price oder quantity)
  • Zeile 2: Anzahl der Produkte
  • Folgende Zeilen: Produktdetails (Name, Preis, Menge – drei Zeilen pro Produkt)

Zum Beispiel bei folgender Eingabe:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Deine Ausgabe sollte folgendermaßen aussehen:

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

Und bei folgender Eingabe:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Deine Ausgabe sollte folgendermaßen aussehen:

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

Beachte, wie dieselben Produktdaten einfach durch die Verwendung eines anderen benannten Typs unterschiedlich sortiert werden können. Sobald deine Typen sort.Interface erfüllen, funktionieren sie nahtlos mit sort.Sort() aus der Standardbibliothek.

Probier es selbst

package main

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

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

	// Sortiermodus lesen
	var mode string
	fmt.Fscanln(reader, &mode)

	// Anzahl der Produkte lesen
	var count int
	fmt.Fscanln(reader, &count)

	// Produkte lesen
	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: Produkte basierend auf dem Modus sortieren
	// Wenn mode "price" ist, verwende den ByPrice-Typ
	// Wenn mode "quantity" ist, verwende den ByQuantity-Typ
	// Verwende sort.Sort() mit dem entsprechenden Typ

	// TODO: Gib jedes Produkt im Format aus:
	// [Name]: $[Price] (x[Quantity])
	// Verwende fmt.Printf mit %.2f für die Preisformatierung
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Go-Compiler