Menu
Coddy logo textTech

Punteros como valores de Map

Parte de la sección Lógica y Flujo del Journey de GO de Coddy. Lección 27 de 68.

Aunque almacenar estructuras directamente en mapas es útil, almacenar punteros a estructuras desbloquea una capacidad muy potente: la posibilidad de modificar directamente los datos de la estructura original a través del mapa. Este enfoque es esencial cuando necesitas actualizar tus datos después de haberlos almacenado.

Cuando almacenas un puntero a una estructura como valor de un mapa, almacenas la dirección de memoria de la estructura, no una copia de ella. Así es como declaras y trabajas con un mapa de este tipo:

type Product struct {
    Price    float64
    Quantity int
}

products := map[string]*Product{
    "laptop": &Product{Price: 999.99, Quantity: 5},
    "mouse":  &Product{Price: 25.50, Quantity: 20},
}

La ventaja clave queda clara cuando necesitas modificar los datos. Como estás trabajando con punteros, los cambios realizados a través del mapa afectan a la estructura original:

// Actualiza el precio de la laptop directamente a través del mapa
products["laptop"].Price = 899.99
fmt.Println(products["laptop"].Price) // imprime: 899.99

Este patrón es especialmente valioso en aplicaciones en las que necesitas actualizar con frecuencia los datos almacenados, como sistemas de inventario, perfiles de usuario o cualquier escenario en el que el mapa sirva como tu almacén de datos principal y las modificaciones deban persistir.

challenge icon

Desafío

Fácil

Construye un sistema sencillo de gestión de inventario que demuestre el poder de usar punteros a estructuras como valores de un mapa. Este desafío muestra cómo los mapas basados en punteros permiten modificar directamente los datos almacenados, haciendo que tu sistema de inventario sea eficiente y responda a las actualizaciones.

Recibirás tres entradas:

  • Una cadena que representa el número de productos (por ejemplo, "4")
  • Una cadena que contiene los datos de los productos con el formato: "name1:price1:quantity1,name2:price2:quantity2,name3:price3:quantity3" (por ejemplo, "laptop:999.99:5,mouse:25.50:20,keyboard:75.00:15,monitor:299.99:8")
  • Una cadena que contiene operaciones de actualización con el formato: "operation1:product1:value1,operation2:product2:value2", donde las operaciones son "price" o "quantity" (por ejemplo, "price:laptop:899.99,quantity:mouse:25,price:keyboard:65.00")

Tu tarea es:

  1. Define una estructura Product con los siguientes campos:
    • Price (float64): el precio del producto
    • Quantity (int): la cantidad de productos en stock
  2. Crea un mapa donde las claves sean los nombres de los productos (cadenas) y los valores sean punteros a estructuras Product
  3. Analiza los datos de los productos de la segunda entrada:
    • Divide la entrada por comas para obtener las entradas individuales de los productos
    • Para cada entrada, divídela por dos puntos para separar el nombre, el precio y la cantidad
    • Convierte la cadena del precio a un float64 y la cadena de la cantidad a un entero
    • Crea una estructura Product y almacena un puntero a ella en el mapa
  4. Mantén los nombres de los productos en un slice separado mientras los analizas, en el orden en que aparecen en la entrada. Recorrer un mapa en Go visita las claves en un orden aleatorio, por lo que el slice es lo que mantiene cada listado en el orden de entrada.
  5. Muestra el inventario inicial con el encabezado "Initial Inventory:"
  6. Muestra cada producto con el formato: "[name]: $[price] (Stock: [quantity])"
  7. Analiza y aplica las operaciones de actualización de la tercera entrada:
    • Divide la entrada por comas para obtener las operaciones individuales
    • Para cada operación, divídela por dos puntos para obtener el tipo de operación, el nombre del producto y el nuevo valor
    • Actualiza el campo correspondiente directamente a través del puntero del mapa
    • Imprime cada actualización con el formato: "Updated [product]: [field] changed to [new_value]"
  8. Muestra el inventario actualizado con el encabezado "Updated Inventory:"
  9. Muestra cada producto nuevamente con el mismo formato que en la visualización inicial
  10. Calcula y muestra el valor total del inventario: "Total Inventory Value: $[total_value]"

Usa el paquete strconv para convertir las cadenas de precios y cantidades a sus respectivos tipos numéricos. Da formato a todos los precios con 2 decimales al mostrarlos. Este desafío demuestra cómo almacenar punteros en mapas permite modificar directamente los datos de la estructura original, haciendo que las actualizaciones del inventario sean inmediatas y persistentes sin necesidad de reasignar valores al mapa.

Pruébalo tú mismo

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// Leer entrada
	var numProductsStr string
	var productDataStr string
	var operationsStr string
	
	fmt.Scanln(&numProductsStr)
	fmt.Scanln(&productDataStr)
	fmt.Scanln(&operationsStr)
	
	// TODO: Define la struct Product aquí
	
	// TODO: Crea un map para almacenar punteros a productos
	
	// TODO: Crea un slice para mantener el orden de los productos (para asegurar una salida consistente)
	
	// TODO: Analiza los datos de productos y rellena el map
	// Recuerda:
	// - Divide productDataStr por comas para obtener entradas individuales
	// - Para cada entrada, divide por dos puntos para obtener name, price, quantity
	// - Convierte las cadenas de price y quantity a los tipos apropiados
	// - Almacena el puntero a la struct Product en el map
	// - Añade el name del producto al slice order
	
	// TODO: Display initial inventory
	// Usa el slice order para iterar a través de los productos de forma consistente
	// Formato: "[name]: $[price] (Stock: [quantity])"
	
	// TODO: Analizar y aplicar las operaciones de actualización
	// Recuerda:
	// - Dividir operationsStr por comas para obtener las operaciones individuales
	// - Para cada operación, dividir por dos puntos para obtener type, name, value
	// - Actualizar el campo apropiado directamente a través del puntero del map
	// - Imprimir el mensaje de actualización para cada operación
	
	// TODO: Display updated inventory
	// De nuevo, usar el slice order para una salida consistente
	// Calcular el valor total mientras se muestra
	
	// TODO: Calculate and display total inventory value
	// Format: "Total Inventory Value: $[total_value]"
}
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 Lógica y Flujo

Practica por tu cuenta: Compilador de Go online