Menu
Coddy logo textTech

sort.Interface

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 74 di 107.

Il pacchetto sort offre un altro ottimo esempio di progettazione basata sulle interfacce. Per ordinare una raccolta personalizzata, il tuo tipo deve implementare sort.Interface:

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

Questi tre metodi forniscono all’algoritmo di ordinamento tutto ciò di cui ha bisogno: la lunghezza della collezione, un modo per confrontare gli elementi e un modo per scambiarli. Ecco come rendere ordinabile una slice di struct personalizzate:

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

L'intuizione chiave consiste nel creare un tipo denominato (ByAge) basato sulla tua slice. Questo ti permette di definire comportamenti di ordinamento diversi per gli stessi dati. Potresti creare ByName con un'implementazione diversa di Less per ordinare alfabeticamente.

Una volta che il tuo tipo soddisfa sort.Interface, funziona automaticamente con sort.Sort(), sort.Reverse() e sort.IsSorted().

challenge icon

Sfida

Facile

Costruiamo un sistema di inventario dei prodotti ordinabile che dimostri la potenza di sort.Interface di Go! Creerai un tipo Product e implementerai diverse strategie di ordinamento, così da poter ordinare la stessa raccolta in modi diversi.

Organizzerai il codice in due file:

  • product.go: definisci il tipo di prodotto e le implementazioni dell'ordinamento.

    Crea una struct Product con tre campi: Name (string), Price (float64) e Quantity (int).

    Crea due tipi con nome basati su []Product:

    • ByPrice - per ordinare i prodotti per prezzo in ordine crescente
    • ByQuantity - per ordinare i prodotti per quantità in ordine decrescente (prima la quantità maggiore)

    Ogni tipo deve implementare i tre metodi richiesti da sort.Interface: Len(), Less(i, j int) e Swap(i, j int). Il metodo Less determina l'ordine di ordinamento per ciascun tipo.

  • main.go: crea e ordina l'inventario dei prodotti.

    Leggi una modalità di ordinamento (price o quantity), poi leggi un numero seguito dai dettagli dei prodotti. Ogni prodotto è fornito su tre righe: nome, prezzo e quantità.

    Crea una slice di prodotti, ordinali usando il tipo di ordinamento appropriato in base alla modalità, quindi stampa ogni prodotto in questo formato:

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

    Visualizza i prezzi con due cifre decimali.

Verranno forniti i seguenti input:

  • Riga 1: modalità di ordinamento (price o quantity)
  • Riga 2: numero di prodotti
  • Righe successive: dettagli dei prodotti (nome, prezzo, quantità - tre righe per prodotto)

Ad esempio, dato:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

L'output dovrebbe essere:

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

E dato:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

L'output dovrebbe essere:

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

Nota come gli stessi dati dei prodotti possano essere ordinati in modo diverso semplicemente usando un diverso tipo con nome. Una volta che i tuoi tipi soddisfano sort.Interface, funzionano senza problemi con sort.Sort() della libreria standard.

Provalo tu

package main

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

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

	// Leggi la modalità di ordinamento
	var mode string
	fmt.Fscanln(reader, &mode)

	// Leggi il numero di prodotti
	var count int
	fmt.Fscanln(reader, &count)

	// Leggi i prodotti
	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: Ordina i prodotti in base a mode
	// Se mode è "price", usa il tipo ByPrice
	// Se mode è "quantity", usa il tipo ByQuantity
	// Usa sort.Sort() con il tipo appropriato

	// TODO: Stampa ogni prodotto nel formato:
	// [Name]: $[Price] (x[Quantity])
	// Usa fmt.Printf con %.2f per formattare il prezzo
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online