Menu
Coddy logo textTech

sort.Interface

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

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

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

Diese drei Methoden geben dem Sortieralgorithmus alles, was er benötigt: die Länge der Sammlung, eine Möglichkeit, Elemente zu vergleichen, und eine Möglichkeit, sie zu vertauschen. Hier erfahren Sie, wie Sie einen Slice aus benutzerdefinierten Structs sortierbar machen:

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 ist das Erstellen eines benannten Typs (ByAge) basierend auf Ihrem Slice. Dies ermöglicht es Ihnen, verschiedene Sortierverhalten für dieselben Daten zu definieren. Sie könnten ByName mit einer anderen Less-Implementierung erstellen, um stattdessen alphabetisch zu sortieren.

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

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein sortierbares Produktinventarsystem bauen, das die Leistungsfähigkeit von Gos sort.Interface demonstriert! Sie werden einen Product-Typ erstellen und mehrere Sortierstrategien implementieren, die es ermöglichen, dieselbe Sammlung auf verschiedene Arten zu sortieren.

Sie werden Ihren Code auf zwei Dateien aufteilen:

  • product.go: Definieren Sie Ihren Produkttyp und die Sortierimplementierungen.

    Erstellen Sie ein Product-Struct mit drei Feldern: Name (string), Price (float64) und Quantity (int).

    Erstellen Sie zwei benannte Typen basierend auf []Product:

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

    Jeder Typ muss die drei vom sort.Interface geforderten Methoden implementieren: Len(), Less(i, j int) und Swap(i, j int). Die Less-Methode bestimmt die Sortierreihenfolge für jeden Typ.

  • main.go: Erstellen und sortieren Sie Ihr Produktinventar.

    Lesen Sie einen Sortiermodus (price oder quantity) ein, lesen Sie dann eine Anzahl gefolgt von Produktdetails. Jedes Produkt wird in drei Zeilen angegeben: Name, Preis und Menge.

    Erstellen Sie ein Slice von Produkten, sortieren Sie diese mit dem entsprechenden Sortiertyp basierend auf dem Modus und geben Sie dann jedes Produkt in diesem Format aus:

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

    Zeigen Sie Preise mit zwei Dezimalstellen an.

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, gegeben:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Ihre Ausgabe sollte sein:

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

Und gegeben:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Ihre Ausgabe sollte sein:

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

Beachten Sie, wie dieselben Produktdaten unterschiedlich sortiert werden können, indem Sie einfach einen anderen benannten Typ verwenden. Sobald Ihre Typen das sort.Interface erfüllen, arbeiten sie nahtlos mit sort.Sort() aus der Standardbibliothek zusammen.

Spickzettel

Das Paket sort erfordert, dass Typen das sort.Interface implementieren, um sortierbar zu sein:

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

Um ein benutzerdefiniertes Slice sortierbar zu machen, erstellen Sie einen benannten Typ und implementieren Sie die drei erforderlichen Methoden:

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

// Die Sammlung sortieren
sort.Sort(ByAge(people))

Sie können mehrere benannte Typen für dasselbe Slice erstellen, um verschiedene Sortierverhalten zu implementieren. Jeder Typ definiert seine eigene Less-Methode, um die Sortierreihenfolge festzulegen.

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

Probier es selbst

package main

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

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 = name[:len(name)-1] // Zeilenumbruch entfernen

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

	// TODO: Jedes Produkt im folgenden Format ausgeben:
	// [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