Menu
Coddy logo textTech

group_by und partition

Teil des Abschnitts Logik & Programmfluss der Ruby-Journey von Coddy — Lektion 25 von 56.

Manchmal möchten Sie eine Collection aufteilen, anstatt sie zu filtern. Zwei Methoden decken die meisten Fälle ab.

group_by nimmt einen Block entgegen und gibt einen Hash zurück. Jedes eindeutige Ergebnis des Blocks wird zu einem Schlüssel, der auf ein Array der Elemente verweist, die dieses Ergebnis erzeugt haben:

words = ["hi", "hello", "yo", "hey", "bonjour"]
by_length = words.group_by { |w| w.length }
puts by_length.inspect
# {2=>["hi", "yo"], 5=>["hello"], 3=>["hey"], 7=>["bonjour"]}

Es ist der sauberste Weg, Elemente in einem Durchgang zu gruppieren.

partition ist die binäre Version: Sie gibt ein Paar von Arrays zurück, die Elemente, für die der Block wahr war, und den Rest:

evens, odds = [1, 2, 3, 4, 5].partition { |n| n.even? }
puts evens.inspect   # [2, 4]
puts odds.inspect    # [1, 3, 5]

Verwenden Sie partition, wenn es genau zwei Buckets gibt, und group_by, wenn es viele sein können.

challenge icon

Aufgabe

Mittel

Lies eine kommagetrennte Liste von name:score Einträgen (z. B. Alice:88,Bob:42,Charlie:75). Verwende group_by gefolgt von partition, um einen kleinen Bericht zu erstellen.

Schritte:

  1. Parse jeden Eintrag in ein [name, score] Paar (score ist eine Ganzzahl)
  2. group_by nach dem ersten Buchstaben des name (großgeschrieben)
  3. Für jede Buchstabengruppe, in alphabetischer Reihenfolge, partition die Einträge in bestehend (score >= 60) und nicht bestehend, und gib dann eine Zeile pro Gruppe aus:
<LETTER>: pass=<names_passing_joined_by_comma> fail=<names_failing_joined_by_comma>

Innerhalb jeder Gruppe erscheinen die Namen in ihrer ursprünglichen Reihenfolge. Wenn eine Seite keine Namen hat, lass sie leer (z. B. fail=).

Für die Eingabe Alice:88,Adam:42,Bob:75,Beth:55,Cara:90 lautet die Ausgabe:

A: pass=Alice fail=Adam
B: pass=Bob fail=Beth
C: pass=Cara fail=

Spickzettel

group_by teilt eine Sammlung in einen Hash auf, der nach dem Ergebnis des Blocks indiziert ist:

words = ["hi", "hello", "yo"]
by_length = words.group_by { |w| w.length }
# {2=>["hi", "yo"], 5=>["hello"]}

partition teilt in genau zwei Arrays auf (übereinstimmend und nicht übereinstimmend):

evens, odds = [1, 2, 3, 4, 5].partition { |n| n.even? }
# evens => [2, 4], odds => [1, 3, 5]

Verwenden Sie partition für zwei Kategorien, group_by für viele.

Probier es selbst

entries = gets.chomp.split(",").map do |s|
  name, score = s.split(":")
  [name, score.to_i]
end

# TODO: nach erstem Buchstaben gruppieren (groß), jede Gruppe nach score >= 60 aufteilen,
#       'X: pass=... fail=...' in alphabetischer Reihenfolge der Buchstaben ausgeben
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