Zusammenführen und Transformieren
Teil des Abschnitts Logik & Programmfluss der Ruby-Journey von Coddy — Lektion 36 von 56.
Zwei Operationen kommen bei der Arbeit mit Hashes so oft vor, dass Ruby ihnen eigene Methoden gibt.
merge kombiniert zwei Hashes zu einem neuen. Wenn beide denselben Schlüssel haben, gewinnt der Wert auf der rechten Seite:
defaults = { color: "red", size: "M" }
custom = { size: "L" }
settings = defaults.merge(custom)
puts settings.inspect # {color: "red", size: "L"}Keines der Originale wird verändert, merge gibt einen neuen Hash zurück.
transform_values erstellt einen neuen Hash mit denselben Schlüsseln, wobei jedoch jeder Wert durch einen Block verarbeitet wird:
prices = { apple: 1, bread: 3 }
with_tax = prices.transform_values { |p| p * 1.2 }
puts with_tax.inspect # {apple: 1.2, bread: 3.6}Und transform_keys macht dasselbe für Schlüssel, nützlich beim Konvertieren von Strings in Symbole oder beim Normalisieren der Groß-/Kleinschreibung:
{ "a" => 1, "B" => 2 }.transform_keys(&:upcase)
# {"A"=>1, "B"=>2}Aufgabe
MittelZwei Warenkorb-Hashes sind gegeben: monday und tuesday, wobei jeder einen String-Artikelnamen auf eine ganzzahlige Menge abbildet. Der Laden möchte eine normalisierte Summe für zwei Tage.
Erstellen Sie einen finalen Hash durch:
merge-en der beiden Hashes mit einem Block, sodass Schlüssel, die in beiden vorhanden sind, ihre Mengen summiert bekommen (nicht überschrieben)transform_keys(&:to_sym)auf das Ergebnis anwenden, damit die Schlüssel zu Symbolen werdentransform_valuesanwenden, um einen Mengenrabatt von 10 % zu gewähren: Jede Menge wird zu(qty * 9 / 10)unter Verwendung von Ganzzahlarithmetik
Geben Sie den finalen Hash mit inspect aus.
Für die Standarddaten lautet die Ausgabe:
{:apples=>9, :bread=>4, :milk=>5, :cheese=>1}(Apples: 5 + 5 = 10, dann 9. Bread: 3 + 2 = 5, dann 4. Milk: 6 nur am Monday → 5. Cheese: 2 nur am Tuesday → 1.)
Spickzettel
merge kombiniert zwei Hashes; bei Schlüsselkonflikten gewinnt der Wert auf der rechten Seite:
defaults = { color: "red", size: "M" }
custom = { size: "L" }
settings = defaults.merge(custom)
# {color: "red", size: "L"}Übergeben Sie einen Block an merge, um doppelte Schlüssel manuell zu behandeln:
a.merge(b) { |key, old_val, new_val| old_val + new_val }transform_values gibt einen neuen Hash zurück, bei dem jeder Wert durch einen Block verarbeitet wurde:
prices = { apple: 1, bread: 3 }
prices.transform_values { |p| p * 1.2 }
# {apple: 1.2, bread: 3.6}transform_keys macht dasselbe für Schlüssel:
{ "a" => 1 }.transform_keys(&:upcase) # {"A"=>1}
{ "a" => 1 }.transform_keys(&:to_sym) # {a: 1}Probier es selbst
monday = { "apples" => 5, "bread" => 3, "milk" => 6 }
tuesday = { "apples" => 5, "bread" => 2, "cheese" => 2 }
# TODO: merge-with-block, um überlappende Schlüssel zu summieren, dann Schlüssel symbolisieren,
# dann * 9 / 10 auf jeden Wert anwenden, dann inspect
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Programmfluss
1Strings im Detail
String-Methoden im ÜberblickString-InterpolationIterieren über StringsSplit und JoinRückblick – String Weaver4Blöcke, Procs & Lambdas
Was ist ein Block?do..end vs. geschweifte KlammernDas yield-SchlüsselwortBlock-ParameterProcs und LambdasZusammenfassung – Eigener Iterator7Hashes Teil 2
Hash.new mit StandardwertenIterieren über HashesVerschachtelte HashesZusammenführen und TransformierenRückblick – Häufigkeitszähler10Projekt - Studentenverwaltung
ProjektübersichtStudent hinzufügen5Enumerable-Kraftpaket
Select und RejectMap-VerkettungReduce / Injectcount, all?, any?, none?group_by und partitionsort_by, min_by, max_byZusammenfassung – Data Pipeline8Fortgeschrittene Entscheidungslogik
Case mit Klassen & RegexMulti-Value whenTernärer OperatorInline if / unlessRückblick – Noten-Klassifizierer