Руководство для начинающих разработчиков.
Представьте, что у нас есть корзина с фруктами, и мы хотим вытащить только яблоки.
Как бы мы поступили в Ruby, если бы наша корзина с фруктами была массивом, а фрукты — строками? Рассмотрим несколько разных способов. Вот наша корзина с фруктами.
fruit_basket = [‘apple’, ‘banana’, ‘apple’, ‘apple’, ‘pear’, ‘orange’]
Когда я был кодером, я узнал о each
. Я так любил each
. Каждая проблема выглядела как гвоздь, а each
был моим прекрасным блестящим молотком.
В то время я бы решил проблему с яблоками с помощью кода, который выглядел бы так.
def get_apples_with_each(fruit_basket) apple_basket = [] fruit_basket.each do |food| if food == ‘apple’ apple_basket << food end end return apple_basket end
Этот код начинается с формирования нового массива. Затем он перебирает массив с помощью each
, выбирая каждую строку, начинающуюся с яблока. Элементы Apple будут перелопачиваться в новый массив по мере продвижения.
Зачем нам пустой массив? Мы не можем просто вернуть each statement
? Поскольку each
имеет возвращаемое значение массива original, он был передан.
Позже в своей карьере я понял, что можно избежать пустого массива, используя collect
, который, в отличие от each
, возвращает новый массив.
Примечание:collect
точно такое же, какmap
. В настоящее время я больше склонен использоватьmap
, чемcollect
, просто потому, чтоmap
короче и программисты ленивы, но на самом деле это не имеет значения. Когда я был новичком, я предпочитал печататьcollect
, потому что сначала я научился этому. В любом случае, давайте посмотрим на наш новый метод.
def get_apples_with_collect(fruit_basket) fruit_basket.collect do |food| if food == ‘apple’ food end end end
Вау, теперь все намного проще! Но что мы получаем взамен?
[“apple”, nil, “apple”, “apple”, nil, nil]
Что такое nil
? Я не могу есть nil
. Бьюсь об заклад, это ужасно на вкус.
Проблема в том, что возвращаемый массив collect
должен принимать значение на каждой итерации, а в случаях, когда фрукт не является яблоком, вместо него помещается nil
.
Мы можем очистить этот результат с помощью милого маленького метода под названием compact
. Compact удаляет все nil
из массива. Компакт идеально подходит для этого случая!
def get_apples_with_collect_compacted(fruit_basket) result = fruit_basket.collect do |food| if food == ‘apple’ food end end return result.compact end
Здорово! Это возвращает то, что мы хотим, и это все еще чище, чем использование each
. Бьюсь об заклад, мы могли бы еще больше упростить этот процесс… (в конце концов, P.A.L.).
Как оказалось, Ruby содержит встроенный метод для поиска и извлечения соответствующих элементов из массива. Этот метод называется select
.
def select_apples(fruit_basket) fruit_basket.select{|food| food == ‘apple’} end
СВЯТОЙ ЯБЛОЧНЫЙ ПИРОГ!
Это всего лишь одна строка кода!
Однако для наших начинающих это выглядит немного пугающе.
Давайте разберем функциональность select
.
Подобно collect
и each
, select
перебирает массив. select
также принимает блок. Каждый раз, когда содержимое блока истинно, он добавляет значение перечисления (значение, которое в данный момент просматривается) к возвращаемому массиву.
В настоящее время, когда дело доходит до извлечения элементов из массива, я чаще использую select
, чем each
или collect
. Тем не менее, each
и collect
являются мощными инструментами, которые можно использовать по-своему. По мере того, как мы растем как разработчики, мы добавляем новые инструменты в наш набор инструментов, но редко отказываемся от старых инструментов. Другими словами, когда-нибудь ваш молот будет выглядеть вот так!
Разница между find_all
и select
Если вы зашли так далеко и у вас есть некоторое представление о Ruby, вам может быть интересно, почему я использовал select
вместо find_all
. Правда в том, что когда вы работаете с массивом, это не имеет значения.
Однако при работе с хешами select
вернет хэш, а find_all
вернет массив. Небольшой бонус на заметку!