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}Desafío
IntermedioSe 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:
merge-ando los dos hashes con un bloque para que las claves presentes en ambos tengan sus cantidades sumadas (no sobrescritas)transform_keys(&:to_sym)en el resultado, para que las claves se conviertan en símbolostransform_valuespara 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
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
1Strings en profundidad
Visión general de los métodos de StringInterpolación de StringsIterar sobre StringsSplit y JoinRepaso - String Weaver4Bloques, Procs y Lambdas
¿Qué es un bloque?do..end vs llavesLa palabra clave yieldParámetros de bloqueProcs y LambdasResumen - Iterador personalizado7Hashes Parte 2
Hash.new con valores por defectoIteración de HashesHashes anidadosFusión y transformaciónResumen - Contador de frecuencia10Proyecto - Registros de Estudiantes
Descripción general del proyectoAgregar estudiante5Potencia de Enumerable
Select y RejectEncadenando MapReduce / Injectcount, all?, any?, none?group_by y partitionsort_by, min_by, max_byResumen - Data Pipeline