Menu
Coddy logo textTech

Mesclando e Transformando

Parte da seção Lógica e Fluxo do Journey de Ruby da Coddy — lição 36 de 56.

Duas operações surgem com tanta frequência ao trabalhar com hashes que o Ruby fornece a elas seus próprios métodos.

merge combina dois hashes em um novo. Quando ambos possuem a mesma chave, o valor da direita vence:

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

Nenhum original é modificado, merge retorna um novo hash.

transform_values constrói um novo hash com as mesmas chaves, mas com cada valor passado por um bloco:

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

E o transform_keys faz o mesmo para as chaves, sendo útil ao converter strings para símbolos ou normalizar a capitalização:

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

Desafio

Médio

Dois hashes de carrinho são fornecidos: monday e tuesday, cada um mapeia o nome de um item (string) para uma quantidade inteira. A loja deseja um total normalizado de dois dias.

Produza um hash final ao:

  1. Fazer o merge dos dois hashes com um bloco para que as chaves presentes em ambos tenham suas quantidades somadas (não sobrescritas)
  2. Usar transform_keys(&:to_sym) no resultado, para que as chaves se tornem símbolos
  3. Usar transform_values para aplicar um desconto de atacado de 10%: cada quantidade se torna (qty * 9 / 10) usando aritmética inteira

Imprima o hash final com inspect.

Para os dados padrão, a saída é:

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

(Apples: 5 + 5 = 10, depois 9. Bread: 3 + 2 = 5, depois 4. Milk: 6 apenas na Monday → 5. Cheese: 2 apenas na Tuesday → 1.)

Folha de consulta

merge combina dois hashes; quando as chaves conflitam, o valor da direita vence:

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

Passe um bloco para merge para lidar com chaves duplicadas manualmente:

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

transform_values retorna um novo hash com cada valor passado através de um bloco:

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

transform_keys faz o mesmo para as chaves:

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

Experimente você mesmo

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

# TODO: merge-with-block para somar chaves sobrepostas, depois transformar chaves em símbolos,
#       depois aplicar * 9 / 10 a cada valor, então inspecionar
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica e Fluxo