Menu
Coddy logo textTech

Interfaz sort.Interface

Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy. Lección 74 de 107.

El paquete sort proporciona otro excelente ejemplo de diseño basado en interfaces. Para ordenar una colección personalizada, tu tipo debe implementar sort.Interface:

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

Estos tres métodos proporcionan al algoritmo de ordenación todo lo que necesita: la longitud de la colección, una forma de comparar elementos y una forma de intercambiarlos. Así es como puedes hacer que un slice de estructuras personalizadas se pueda ordenar:

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

La idea clave es crear un tipo con nombre (ByAge) basado en tu slice. Esto te permite definir diferentes comportamientos de ordenación para los mismos datos. Podrías crear ByName con una implementación diferente de Less para ordenar alfabéticamente en su lugar.

Una vez que tu tipo satisface sort.Interface, funciona automáticamente con sort.Sort(), sort.Reverse() y sort.IsSorted().

challenge icon

Desafío

Fácil

¡Construyamos un sistema de inventario de productos ordenable que demuestre el poder de sort.Interface de Go! Crearás un tipo Product e implementarás varias estrategias de ordenación, lo que permitirá ordenar la misma colección de diferentes maneras.

Organizarás tu código en dos archivos:

  • product.go: Define tu tipo de producto y las implementaciones de ordenación.

    Crea una estructura Product con tres campos: Name (string), Price (float64) y Quantity (int).

    Crea dos tipos con nombre basados en []Product:

    • ByPrice - para ordenar los productos por precio en orden ascendente
    • ByQuantity - para ordenar los productos por cantidad en orden descendente (la cantidad más alta primero)

    Cada tipo debe implementar los tres métodos requeridos por sort.Interface: Len(), Less(i, j int) y Swap(i, j int). El método Less determina el orden de ordenación para cada tipo.

  • main.go: Construye y ordena tu inventario de productos.

    Lee un modo de ordenación (price o quantity), después lee una cantidad seguida de los detalles de los productos. Cada producto se proporciona en tres líneas: nombre, precio y cantidad.

    Crea un slice de productos, ordénalo usando el tipo de ordenación correspondiente según el modo y, después, imprime cada producto con este formato:

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

    Muestra los precios con dos decimales.

Se proporcionarán las siguientes entradas:

  • Línea 1: Modo de ordenación (price o quantity)
  • Línea 2: Número de productos
  • Líneas siguientes: Detalles del producto (nombre, precio, cantidad: tres líneas por producto)

Por ejemplo, dada la siguiente entrada:

price
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Tu salida debería ser:

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

Y dada la siguiente entrada:

quantity
3
Laptop
999.99
5
Mouse
29.99
50
Keyboard
79.99
25

Tu salida debería ser:

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

Observa cómo los mismos datos de productos pueden ordenarse de manera diferente simplemente usando un tipo con nombre distinto. Una vez que tus tipos satisfacen sort.Interface, funcionan perfectamente con sort.Sort() de la biblioteca estándar.

Pruébalo tú mismo

package main

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

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

	// Leer el modo de ordenación
	var mode string
	fmt.Fscanln(reader, &mode)

	// Leer el número de productos
	var count int
	fmt.Fscanln(reader, &count)

	// Leer los productos
	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: Ordenar los productos según el modo
	// Si el modo es "price", usa el tipo ByPrice
	// Si el modo es "quantity", usa el tipo ByQuantity
	// Usa sort.Sort() con el tipo apropiado

	// TODO: Imprimir cada producto en el formato:
	// [Name]: $[Price] (x[Quantity])
	// Usa fmt.Printf con %.2f para el formato del precio
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Go online