group_by i partition
Część sekcji Logika i przepływ programu ścieżki Ruby w Coddy. Lekcja 25 z 56.
Czasami zamiast filtrować kolekcję, chcesz ją podzielić. Dwie metody sprawdzają się w większości przypadków.
group_by przyjmuje blok i zwraca skrót. Każdy unikalny wynik bloku staje się kluczem, do którego przypisana jest tablica elementów, które go wygenerowały:
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"]}To najprostszy sposób na grupowanie elementów w jednym przebiegu.
partition to wersja binarna: zwraca parę tablic — elementy, dla których blok zwrócił wartość true, oraz pozostałe:
evens, odds = [1, 2, 3, 4, 5].partition { |n| n.even? }
puts evens.inspect # [2, 4]
puts odds.inspect # [1, 3, 5]Użyj partition, gdy są dokładnie dwa zbiory, a group_by, gdy może ich być wiele.
Wyzwanie
ŚredniWczytaj listę wpisów name:score rozdzielonych przecinkami (np. Alice:88,Bob:42,Charlie:75). Użyj group_by, a następnie partition, aby utworzyć krótki raport.
Kroki:
- Przekształć każdy wpis w parę
[name, score](score jest liczbą całkowitą) - Pogrupuj pary za pomocą
group_bywedług pierwszej literyname(wielkiej) - Dla każdej grupy liter, w kolejności alfabetycznej, podziel wpisy za pomocą
partitionna zdające (score >= 60) i niezdające, a następnie wypisz po jednym wierszu dla każdej grupy:
<LETTER>: pass=<names_passing_joined_by_comma> fail=<names_failing_joined_by_comma>W każdej grupie imiona występują w pierwotnej kolejności. Jeśli po którejś stronie nie ma żadnych imion, pozostaw ją pustą (np. fail=).
Dla danych wejściowych Alice:88,Adam:42,Bob:75,Beth:55,Cara:90 wynik to:
A: pass=Alice fail=Adam
B: pass=Bob fail=Beth
C: pass=Cara fail=Spróbuj swoich sił
entries = gets.chomp.split(",").map do |s|
name, score = s.split(":")
[name, score.to_i]
end
# TODO: pogrupuj według pierwszej litery (wielkiej), podziel każdą grupę według score >= 60,
# wypisz 'X: pass=... fail=...' w kolejności alfabetycznej liter
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ programu
1Łańcuchy znaków w szczegółach
Przegląd metod łańcuchów znakówInterpolacja łańcuchów znakówIterowanie po łańcuchach znakówDzielenie i łączeniePowtórka – Tkacz łańcuchów znaków4Bloki, procki i lambdy
Czym jest blok?do..end a nawiasy klamroweSłowo kluczowe yieldParametry blokuProcki i lambdyPodsumowanie — własny iterator7Hashe, część 2
Hash.new z wartościami domyślnymiIterowanie po haszachZagnieżdżone haszeŁączenie i przekształcaniePowtórka — licznik częstotliwości10Projekt – ewidencja uczniów
Przegląd projektuDodawanie ucznia5Potęga Enumerable
Select i RejectŁączenie wywołań mapReduce / Injectcount, all?, any?, none?group_by i partitionsort_by, min_by, max_byPodsumowanie — potok danych8Zaawansowane podejmowanie decyzji
case z klasami i wyrażeniami regularnymiwhen z wieloma wartościamiOperator trójargumentowyInline if / unlessPowtórka – klasyfikator ocenPoćwicz samodzielnie: Kompilator Ruby online