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]