Menu
Coddy logo textTech

Fusion et transformation

Fait partie de la section Logique et Flux du Journey Ruby de Coddy — leçon 36 sur 56.

Deux opérations reviennent si souvent lorsqu'on travaille avec des hashs que Ruby leur donne leurs propres méthodes.

merge combine deux hashs en un nouveau. Lorsque les deux ont la même clé, la valeur de droite l'emporte :

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

Aucun des originaux n'est modifié, merge retourne un nouveau hash.

transform_values construit un nouveau hash avec les mêmes clés, mais chaque valeur est passée à travers un bloc :

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

Et transform_keys fait la même chose pour les clés, ce qui est utile lors de la conversion de chaînes de caractères en symboles, ou pour normaliser la casse :

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

Défi

Moyen

Deux hashes de paniers sont donnés : monday et tuesday, chacun associant un nom d'article sous forme de chaîne de caractères à une quantité entière. Le magasin souhaite obtenir un total normalisé sur deux jours.

Produisez un hash final en :

  1. Utilisant merge pour fusionner les deux hashes avec un bloc afin que les clés présentes dans les deux voient leurs quantités additionnées (et non écrasées)
  2. Utilisant transform_keys(&:to_sym) sur le résultat, pour que les clés deviennent des symboles
  3. Utilisant transform_values pour appliquer une remise de gros de 10 % : chaque quantité devient (qty * 9 / 10) en utilisant l'arithmétique entière

Affichez le hash final avec inspect.

Pour les données par défaut, la sortie est :

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

(Apples : 5 + 5 = 10, puis 9. Bread : 3 + 2 = 5, puis 4. Milk : 6 uniquement le lundi → 5. Cheese : 2 uniquement le mardi → 1.)

Aide-mémoire

merge combine deux hashs ; en cas de conflit de clés, la valeur de droite l'emporte :

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

Passez un bloc à merge pour gérer manuellement les clés dupliquées :

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

transform_values retourne un nouveau hash dont chaque valeur est passée à travers un bloc :

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

transform_keys fait la même chose pour les clés :

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

Essayez vous-même

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

# TODO: merge-with-block pour additionner les clés qui se chevauchent, puis symboliser les clés,
#       puis appliquer * 9 / 10 à chaque valeur, puis inspecter
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Logique et Flux