Menu
Coddy logo textTech

group_by и partition

Часть раздела Логика и управление потоком путешествия по Ruby на Coddy. Урок 25 из 56.

Иногда вам нужно разделить коллекцию, а не отфильтровать её. Два метода закрывают большинство таких случаев.

group_by принимает блок и возвращает хэш. Каждый уникальный результат блока становится ключом, ссылающимся на массив элементов, которые его сформировали:

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"]}

Это самый чистый способ сгруппировать элементы за один проход.

partition — это бинарная версия: метод возвращает пару массивов — элементы, для которых блок вернул true, и все остальные:

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

Используйте partition, когда есть ровно две группы, и group_by, когда их может быть много.

challenge icon

Задание

Средне

Прочитайте разделённый запятыми список записей name:score (например, Alice:88,Bob:42,Charlie:75). Используйте group_by, а затем partition, чтобы сформировать небольшое отчётное сообщение.

Шаги:

  1. Разберите каждую запись на пару [name, score] (значение score — целое число)
  2. Сгруппируйте с помощью group_by по первой букве имени name (в верхнем регистре)
  3. Для группы каждой буквы в алфавитном порядке (alphabetical order) разделите записи с помощью partition на прошедшие (score >= 60) и непрошедшие, после чего выведите по одной строке на каждую группу:
<LETTER>: pass=<names_passing_joined_by_comma> fail=<names_failing_joined_by_comma>

Внутри каждой группы имена должны идти в их исходном порядке. Если на какой-то стороне нет имён, оставьте её пустой (например, fail=).

Для входных данных Alice:88,Adam:42,Bob:75,Beth:55,Cara:90 вывод будет следующим:

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

Попробуйте сами

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

# TODO: сгруппировать по первой букве (верхний регистр), разбить каждую группу по score >= 60,
#       вывести 'X: pass=... fail=...' в алфавитном порядке букв
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Онлайн-компилятор Ruby