Ruby Iterators
Блоки и итераторы
Возможность вызова методов в отношении целых чисел — это часто используемый аспект Ruby:
3.times { print "Ruby! " } # Выводит "Ruby! Ruby! Ruby! "
l.upto(9) {|xJ print x } # Выводит "123456789"
times и upto — это методы, выполняемые в отношении целочисленных объектов. Они представляют собой особую разновидность методов, известную как итераторы, и ведут себя как циклы и хотя циклы whilе, until и for являются основной частью языка Ruby, все же, проще писать циклы, используя специальные методы - итераторы. Код, помещенный в фигурные скобки, — известный как блок — связан с вызовом метода и служит в качестве тела цикла. Использование итераторов и блоков — еще одно примечательное свойство языка Ruby;
В общем и целом: Итератор (iterator ― перечислитель, от итерация) — интерфейс, предоставляющий доступ к элементам коллекции (массива или контейнера) и навигацию по ним. В различных системах итераторы могут иметь разные общепринятые названия. В терминах систем управления базами данных итераторы называются курсорами. В простейшем случае итератором в низкоуровневых языках является указатель. Или так: Итератор — структура данных, которая «указывает» на некоторый элемент контейнера, и (для некоторых контейнеров) умеет переходить к предыдущему/следующему элементу.
Итераторы — одно из самых замечательных свойств Ruby, и примеры, подобные следующим, часто встречаются во вводных курсах по языку Ruby:
3.times { puts "Спасибо!" } # Троекратное выражение благодарности
data.each {|x| puts x } # Вывод каждого элемента х, имеющегося в data
[1.2,3].map {jx| x*x } # Вычисление квадратов значений элементов массива
factorial = 1 # Вычисление факториала n
2.upto(n) {|x| factorial *= x
Все эти методы — times, each, map и upto, или итераторы, взаимодействуют с блоком кода, который следует за ними. За всем этим стоит сложная структура управления — yield.
Итераторы - это не что иное, как методы, поддерживаемые коллекциями. Коллекция, как водится в Ruby, это объект в котором хранится группа элементов данных. В Ruby массивы и хэши так же можно назвать коллекциями.
Итераторы возвращают все элементы коллекции один за другим. Ниже будем обсуждать два итератора, each и collect. Давайте рассмотрим их подробнее.
Ruby each Iterator
Целые числа — это не только значения, имеющие методы-итераторы. В массивах (и им подобных "перечисляемых объектах") определен итератор по имени each, который однократно вызывает связанный с ним блок для каждого элемента массива. Каждому вызову блока передается отдельный элемент массива.
Синтаксис:
collection.each do |variable|
code
end
Выполняет код для каждого элемента в коллекции. Здесь коллекция может быть массивом или хешем Ruby.
Пример:
#!/usr/bin/ruby
ary = [1,2,3,4,5]
ary.each do |i|
puts i
end
Это даст следующий результат
1
2
3
4
5
Вы всегда связываете каждый итератор с блоком. Он возвращает в блок каждое значение массива одно за другим. Значение сохраняется в переменной i и затем отображается на экране.
Ruby collect Iterator
Итератор сбора (collect) возвращает все элементы коллекции.
Синтаксис:
collection = collection.collect
Метод collect не всегда должен быть связан с блоком. Метод collect возвращает всю коллекцию, независимо от того, является ли она массивом или хешем.
Пример:
#!/usr/bin/ruby
a = [1,2,3,4,5]
b = Array.new
b = a.collect
puts b
Это даст такой результат:
1
2
3
4
5
ПРИМЕЧАНИЕ. - Метод collect не является правильным способом копирования между массивами. Есть еще один метод, называемый clone, который следует использовать для копирования одного массива в другой.
Обычно вы используете метод collect, когда хотите что-то сделать с каждым из значений, чтобы получить новый массив. Например, этот код создает массив b, содержащий 10 раз каждое значение в a.
#!/usr/bin/ruby
a = [1,2,3,4,5]
b = a.collect{|x| 10*x}
puts b
Это даст следующий результат
[10, 20, 30, 40, 50]