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}Défi
MoyenDeux 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 :
- Utilisant
mergepour 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) - Utilisant
transform_keys(&:to_sym)sur le résultat, pour que les clés deviennent des symboles - Utilisant
transform_valuespour 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
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
1Les chaînes de caractères en profondeur
Aperçu des méthodes de chaînesInterpolation de chaînesParcourir les chaînesSplit et JoinRécapitulatif - String Weaver4Blocs, Procs & Lambdas
Qu'est-ce qu'un bloc ?do..end vs AccoladesLe mot-clé yieldParamètres de blocProcs et LambdasRécapitulatif - Itérateur personnalisé7Hashes - Partie 2
Hash.new avec des valeurs par défautItérer sur les HashesHashes imbriquésFusion et transformationRécapitulatif - Compteur de fréquence10Projet - Dossiers étudiants
Présentation du projetAjouter un étudiant2Intervalles
Qu'est-ce qu'un intervalle ?Méthodes d'intervalleLes intervalles dans Case / WhenRécapitulatif - Pratique des intervalles5La puissance d'Enumerable
Select et RejectChaîner MapReduce / Injectcount, all?, any?, none?group_by et partitionsort_by, min_by, max_byRécapitulatif - Data Pipeline