Магия модуля Enumerable в Ruby: #6 Сладкие остатки
января 16, 2011 | Published in Ruby, Основы | 3 Comments
Статьи из цикла Магия модуля Enumerable:
1.Основы
2. Унарный оператор амперсанд “&”
3. Условные операторы
4. Фильтры
5. Создание новых коллекций
6. Методы inject, min и max
Я не смог понять смысла и отношения оригинального названия статьи Aggregates, поэтому назвал статью просто «Методы inject, min и max».
Это последняя статья в цикле статей о модуле Enumerable и методах, которые он в себе содержит и которые позволяют очень удобно работать с коллекциями. В этой статье мы поговорим о методах, которые не возвращают новую коллекцию, а возвращают лишь один объект.
Метод inject
Если вы не использовали этот метод ранее, хочу вам сообщить, что он весьма интересен. Это аккумулирующий метод, который от итерации к итерации сохраняет определенное значение. Классический пример использования метода inject — это нахождение суммы элементов численного массива:
[1, 2, 3].inject{|sum, num| sum += num} #=> 6
Здесь переменная sum — первый аргумент блока в которой и сохраняется результат работы предыдущей итерации.
Другой целью использования может быть нахождение инициалов имен:
['Jaime', 'Lee', 'Bellmyer'].inject(''){|initials, name| initials += name[0,1]} #=> "JLB"
В этом примере я передал начальную строку (», или blank) в метод inject. Иначе метод inject возьмет первый элемент целиком и начнет прибавлять к нему первые буквы от «Lee» и «Bellmyer». Мне не нравится такое поведение, и я подозреваю, что inject работает именно так потому, что предполагает, что вы в такой способ пытаетесь суммировать элементы коллекции. Вы также нуждаетесь в передаче инициирующего значения в inject , когда вы хотите чтобы результат был иного типа, чем элементы коллекции:
[1, 2, 3].inject(0.0){|sum, i| sum += i.to_f} #=> 6.0
Инициирующее значение в inject — это не что иное, как шаблон, который указывает на то, какого типа должно быть возвращаемое значение. » — строка, 0 — целое число, 0.0 — дробное число и т.д.
Методы min и max
У этих методов возможности шире, чем вы могли предполагать. Они очень похожи на метод sort в том, что так же используют метод <=> для поиска соответственно элемента с минимальным и максимальным значением.
['joshua', 'gabriel', 'jacob'].min #=> "gabriel" ['joshua', 'gabriel', 'jacob'].max #=> "joshua" [1,2,3].min #=> 1 [1,2,3].max #=> 3
Мы также можем передать наш собственный блок, по которому будет происходить поиск, так же как мы это делали в предыдущей статье с методом sort:
['joshua', 'gabriel', 'jacob'].min{|a,b| a.reverse <=> b.reverse} #=> "joshua" ['joshua', 'gabriel', 'jacob'].max{|a,b| a.reverse <=> b.reverse} #=> "gabriel" [1,2,3].min{|a,b| a*(-1) <=> b*(-1)} #=> 3 [1,2,3].max{|a,b| a*(-1) <=> b*(-1)} #=> 1
Оригинал статьи на английском:
Лучшая благодарность автору блога — ваши комментарии!
января 28, 2011 at 02:23 (#)
Я не смог понять смысла и отношения оригинального названия статьи Aggregates, поэтому назвал статью просто “Методы inject, min и max”.
Ну почему же, есть же понятие агрегации:
Так что я думаю что Агрегации вполне подходящее название.
ноября 17, 2011 at 22:56 (#)
Автор, установил бы лучше кнопки Контактика, чем всяких сабмитов и дигов.
ноября 25, 2014 at 21:37 (#)
Я бы не сказал, что инициализирующее значение #inject — это шаблон. Скорее, это объект, который далее будет использоваться в качестве аккумулятора.