Menu
Coddy logo textTech

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}
challenge icon

Aufgabe

Mittel

Zwei 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:

  1. merge-en der beiden Hashes mit einem Block, sodass Schlüssel, die in beiden vorhanden sind, ihre Mengen summiert bekommen (nicht überschrieben)
  2. transform_keys(&:to_sym) auf das Ergebnis anwenden, damit die Schlüssel zu Symbolen werden
  3. transform_values anwenden, 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
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Logik & Programmfluss