Menu
Coddy logo textTech

Fusión y transformación

Parte de la sección Lógica y flujo del Journey de Ruby de Coddy — lección 36 de 56.

Dos operaciones surgen con tanta frecuencia al trabajar con hashes que Ruby les otorga sus propios métodos.

merge combina dos hashes en uno nuevo. Cuando ambos tienen la misma clave, el valor de la derecha prevalece:

defaults = { color: "red", size: "M" }
custom   = { size: "L" }
settings = defaults.merge(custom)
puts settings.inspect   # {color: "red", size: "L"}

Ninguno de los originales se modifica, merge devuelve un nuevo hash.

transform_values construye un nuevo hash con las mismas claves pero con cada valor pasado a través de un bloque:

prices = { apple: 1, bread: 3 }
with_tax = prices.transform_values { |p| p * 1.2 }
puts with_tax.inspect   # {apple: 1.2, bread: 3.6}

Y transform_keys hace lo mismo para las claves, lo cual es útil al convertir cadenas a símbolos o al normalizar el uso de mayúsculas y minúsculas:

{ "a" => 1, "B" => 2 }.transform_keys(&:upcase)
# {"A"=>1, "B"=>2}
challenge icon

Desafío

Intermedio

Se proporcionan dos hashes de carritos: monday y tuesday, cada uno mapea un nombre de artículo de tipo string a una cantidad entera. La tienda quiere un total normalizado de dos días.

Produce un hash final mediante:

  1. merge-ando los dos hashes con un bloque para que las claves presentes en ambos tengan sus cantidades sumadas (no sobrescritas)
  2. transform_keys(&:to_sym) en el resultado, para que las claves se conviertan en símbolos
  3. transform_values para aplicar un descuento por volumen del 10%: cada cantidad se convierte en (qty * 9 / 10) usando aritmética de enteros

Imprime el hash final con inspect.

Para los datos por defecto, la salida es:

{:apples=>9, :bread=>4, :milk=>5, :cheese=>1}

(Apples: 5 + 5 = 10, luego 9. Bread: 3 + 2 = 5, luego 4. Milk: 6 solo el lunes → 5. Cheese: 2 solo el martes → 1.)

Hoja de referencia

merge combina dos hashes; cuando las claves entran en conflicto, el valor de la derecha prevalece:

defaults = { color: "red", size: "M" }
custom   = { size: "L" }
settings = defaults.merge(custom)
# {color: "red", size: "L"}

Pasa un bloque a merge para manejar las claves duplicadas manualmente:

a.merge(b) { |key, old_val, new_val| old_val + new_val }

transform_values devuelve un nuevo hash con cada valor pasado a través de un bloque:

prices = { apple: 1, bread: 3 }
prices.transform_values { |p| p * 1.2 }
# {apple: 1.2, bread: 3.6}

transform_keys hace lo mismo para las claves:

{ "a" => 1 }.transform_keys(&:upcase)  # {"A"=>1}
{ "a" => 1 }.transform_keys(&:to_sym)  # {a: 1}

Pruébalo tú mismo

monday  = { "apples" => 5, "bread" => 3, "milk" => 6 }
tuesday = { "apples" => 5, "bread" => 2, "cheese" => 2 }

# TODO: merge-with-block para sumar claves superpuestas, luego simbolizar claves,
#       luego aplicar * 9 / 10 a cada valor, luego inspeccionar
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