Бесплатный курс по Ruby. Зарегистрируйтесь для отслеживания прогресса →

Ruby: Методы массивов

Помимо обычных методов, массивы содержат большое число методов, работающих с блоками. Возьмем для примера метод sort(). Он умеет сортировать только на основе сравнения значений. Такая сортировка сработает в случае простых массивов из чисел, но окажется бесполезной в большинстве реальных ситуаций, где процесс сортировки может быть хитрым. Пример:

# Население стран
data = [
  ['france', 140_000],
  ['usa', 300_000],
  ['germany', 40_000]
]

Как отсортировать страны по количеству жителей в них? Для таких ситуаций и нужны функции высшего порядка:

# Внутрь передается блок,
# который принимает на вход элемент массива
data.sort_by { |row| row[1] }
# [
#   ['germany', 40_000],
#   ['france', 140_000],
#   ['usa', 300_000]
# ]

# Либо, если кода много
data.sort_by do |row|
  row[1]
end

Метод sort_by() ожидает, что из блока вернётся значение, по которому нужно выполнить сортировку. Затем, когда значения собраны, этот метод выполняет сортировку, сравнивая значения с помощью оператора <=>.

Вот некоторые примеры подобных функций:

  • max_by() – поиск максимального по указанному параметру в массиве
  • partition() – разделяет массив на два по указанному условию

Таких функций у массивов десятки. Единственный способ их запомнить – постоянно практиковаться и читать документацию.

Задание

Некая организация занимается аналитикой распространения COVID-19. Одна из её задач – считать ежедневное количество заболевших. Из исходных данных у неё есть ежедневное количество заболевших по странам:

data = [
  ['11-9-2020', 'france', 10_000],
  ['11-10-2020', 'usa', 35_000],
  ['13-12-2020', 'india', 55_000],
  ['12-11-2020', 'france', 13_000],
  ['12-12-2020', 'usa', 22_000],
  ['11-12-2020', 'india', 54_000],
]

Ваша задача — помочь им написать функцию sort_cases(), которая сортирует записи по дате в обратном порядке и возвращает наружу получившийся массив:

result = sort_cases(data)
# result= [
#   ['13-12-2020', 'india', 55_000],
#   ['12-12-2020', 'usa', 22_000],
#   ['11-12-2020', 'india', 54_000],
#   ['12-11-2020', 'france', 13_000],
#   ['11-10-2020', 'usa', 35_000],
#   ['11-9-2020', 'france', 10_000]
# ]

Подсказки

  • Ключом сортировки в данном случае выступает unix timestamp, который можно получить из даты, преобразовав его к объекту типа Time
  • reverse() – метод возвращает элементы массива в обратном порядке
Упражнение не проходит проверку — что делать? 😶

Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:

  • Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨

Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.

Мой код отличается от решения учителя 🤔

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.

В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

Прочитал урок — ничего не понятно 🙄

Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.

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

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе