Поиск…


каждый

Ruby имеет много типов счетчиков, но первый и самый простой тип перечислителя для начала - это each . Мы будем печатать even или odd для каждого номера от 1 до 10 чтобы показать, как each работает.

В принципе есть два способа передать так называемые blocks . block представляет собой часть передаваемого кода, которая будет выполняться вызываемым методом. each метод принимает block который он вызывает для каждого элемента коллекции объектов, на который он был вызван.

Существует два способа передать блок методу:

Способ 1: встроенный

(1..10).each { |i| puts i.even? ? 'even' : 'odd' }

Это очень сжатый и рубиновый способ решить эту проблему. Давайте разложим это по частям.

  1. (1..10) представляет собой диапазон от 1 до 10 включительно. Если бы мы хотели, чтобы это было от 1 до 10 эксклюзивных, мы писали бы (1...10) .
  2. .each - перечислитель, который перечисляет each элемент в объекте, на котором он действует. В этом случае он действует на each число в диапазоне.
  3. { |i| puts i.even? ? 'even' : 'odd' } является блоком для each утверждения, которое само по себе можно разбить дальше.
    1. |i| это означает, что каждый элемент в диапазоне представлен внутри блока идентификатором i .
    2. puts - это метод вывода в Ruby с автоматическим прерыванием строки после каждого его распечатывания. (Мы можем использовать print если мы не хотим, чтобы автоматический разрыв строки)
    3. i.even? проверяет, четный ли i . Мы могли бы также использовать i % 2 == 0 ; однако предпочтительнее использовать встроенные методы.
    4. ? "even" : "odd" - это тернарный оператор рубина. То, как построен тернарный оператор, является expression ? a : b . Это коротко для
    if expression
      a
    else
      b
    end
    

Для кода длиной более одной строки block должен быть передан как multiline block .

Способ 2: Многострочный

(1..10).each do |i|
  if i.even?
    puts 'even'
  else
    puts 'odd'
  end
end

В multiline block do заменяет открывающий кронштейн и end заменяет закрывающий кронштейн из inline стиля.

Ruby поддерживает reverse_each. Он будет перебирать массив назад.

@arr = [1,2,3,4]
puts @arr.inspect # output is [1,2,3,4]

print "Reversed array elements["
@arr.reverse_each do |val|
        print " #{val} " # output is 4 3 2 1
end
print "]\n"

Внедрение в классе

Enumerable - самый популярный модуль в Ruby. Его цель - предоставить вам итеративные методы, такие как map , select , reduce и т. Д. Классы, которые используют Enumerable включают Array , Hash , Range . Чтобы использовать его, вы должны include Enumerable и реализовать each .

class NaturalNumbers
  include Enumerable

  def initialize(upper_limit)
    @upper_limit = upper_limit
  end

  def each(&block)
    0.upto(@upper_limit).each(&block)
  end
end

n = NaturalNumbers.new(6)

n.reduce(:+)                   # => 21
n.select(&:even?)              # => [0, 2, 4, 6]
n.map { |number| number ** 2 } # => [0, 1, 4, 9, 16, 25, 36]

карта

Возвращает измененный объект, но исходный объект остается таким, какой он есть. Например:

arr = [1, 2, 3]
arr.map { |i| i + 1 } # => [2, 3, 4]
arr # => [1, 2, 3]

map! изменяет исходный объект:

arr = [1, 2, 3]
arr.map! { |i| i + 1 } # => [2, 3, 4]
arr # => [2, 3, 4]

Примечание. Вы также можете использовать collect для выполнения той же самой вещи.

Итерация по сложным объектам

Массивы

Вы можете выполнять итерацию по вложенным массивам:

[[1, 2], [3, 4]].each { |(a, b)| p "a: #{ a }", "b: #{ b }" }

Также допускается следующий синтаксис:

[[1, 2], [3, 4]].each { |a, b| "a: #{ a }", "b: #{ b }" }

Будет производить:

"a: 1"
"b: 2"
"a: 3"
"b: 4"

Хэш

Вы можете перебирать пары ключ-значение:

{a: 1, b: 2, c: 3}.each { |pair| p "pair: #{ pair }" }

Будет производить:

"pair: [:a, 1]"
"pair: [:b, 2]"
"pair: [:c, 3]"

Вы можете перебирать ключи и значения одновременно:

{a: 1, b: 2, c: 3}.each { |(k, v)| p "k: #{ k }", "v: #{ k }" }

Будет производить:

"k: a"
"v: a"
"k: b"
"v: b"
"k: c"
"v: c"

Для итератора

Это повторяется от 4 до 13 (включительно).

for i in 4..13
    puts "this is #{i}.th number"
end

Мы также можем перебирать массивы, используя для

names = ['Siva', 'Charan', 'Naresh', 'Manish']

for name in names
    puts name
end

Итерация с индексом

Иногда вы хотите знать позицию ( индекс ) текущего элемента во время итерации над перечислителем. Для этой цели Ruby предоставляет метод with_index . Он может применяться ко всем счетчикам. В принципе, добавив with_index к перечислению, вы можете перечислить это перечисление. Индекс передается блоку в качестве второго аргумента.

[2,3,4].map.with_index { |e, i| puts "Element of array number #{i} => #{e}" }
#Element of array number 0 => 2
#Element of array number 1 => 3
#Element of array number 2 => 4
#=> [nil, nil, nil]

with_index имеет необязательный аргумент - первый индекс, который по умолчанию равен 0 :

[2,3,4].map.with_index(1) { |e, i| puts "Element of array number #{i} => #{e}" }
#Element of array number 1 => 2
#Element of array number 2 => 3
#Element of array number 3 => 4
#=> [nil, nil, nil]

Существует специальный метод each_with_index . Единственное различие между ним и each.with_index заключается в том, что вы не можете передать аргумент этому, поэтому первый индекс равен 0 все время.

[2,3,4].each_with_index { |e, i| puts "Element of array number #{i} => #{e}" }
#Element of array number 0 => 2
#Element of array number 1 => 3
#Element of array number 2 => 4
#=> [2, 3, 4]


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow