Szukaj…


Każdy

Ruby ma wiele typów modułów wyliczających, ale each z each jest pierwszym i najprostszym typem modułu wyliczającego. Wydrukujemy even lub odd dla każdej liczby od 1 do 10 aby pokazać, jak działa each .

Zasadniczo istnieją dwa sposoby przekazywania tak zwanych blocks . block jest przekazywanym fragmentem kodu, który zostanie wykonany za pomocą wywoływanej metody. each metoda pobiera block który wywołuje dla każdego elementu kolekcji obiektów, do których została wywołana.

Istnieją dwa sposoby przekazania bloku do metody:

Metoda 1: Inline

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

Jest to bardzo skompresowany i rubinowy sposób rozwiązania tego problemu. Podzielmy to kawałek po kawałku.

  1. (1..10) to zakres od 1 do 10 włącznie. Gdybyśmy chcieli, aby było to od 1 do 10 wyłączność, napisalibyśmy (1...10) .
  2. .each to .each wyliczający, który wylicza each element w obiekcie, na którym działa. W takim przypadku działa na each liczbę w zakresie.
  3. { |i| puts i.even? ? 'even' : 'odd' } to blok dla each instrukcji, który sam może być dalej podzielony.
    1. |i| oznacza to, że każdy element w zakresie jest reprezentowany w bloku przez identyfikator i .
    2. puts jest metodą wyjściową w Ruby, która ma automatyczny podział linii po każdym wydrukowaniu. (Możemy użyć print jeśli nie chcemy automatycznego dzielenia linii)
    3. i.even? sprawdza, czy i parzysty. Mogliśmy również użyć i % 2 == 0 ; jednak lepiej jest korzystać z wbudowanych metod.
    4. ? "even" : "odd" to trójskładnikowy operator Ruby. Sposób konstruowania operatora trójskładnikowego to expression ? a : b . To jest skrót od
    if expression
      a
    else
      b
    end
    

W przypadku kodu dłuższego niż jedna linia block powinien zostać przekazany jako multiline block .

Metoda 2: Wielowierszowa

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

W multiline block do zastępuje nawias otwierający, a end zastępuje nawias zamykający ze stylu inline .

Ruby obsługuje również reverse_each. Powtórzy tablicę do tyłu.

@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"

Implementacja w klasie

Enumerable to najpopularniejszy moduł w Rubim. Jego celem jest dostarczenie iterowalnych metod, takich jak map , select , reduce itp. Klasy, które używają Enumerable obejmują Array , Hash , Range . Aby z niego skorzystać, musisz include Enumerable i zaimplementować 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]

Mapa

Zwraca zmieniony obiekt, ale oryginalny obiekt pozostaje niezmieniony. Na przykład:

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

map! zmienia oryginalny obiekt:

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

Uwaga: możesz także użyć opcji collect aby zrobić to samo.

Iterowanie po złożonych obiektach

Tablice

Możesz iterować po zagnieżdżonych tablicach:

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

Dozwolona jest również następująca składnia:

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

Będzie produkować:

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

Hashes

Możesz iterować po parach klucz-wartość:

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

Będzie produkować:

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

Możesz iterować klucze i wartości jednocześnie:

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

Będzie produkować:

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

Dla iteratora

Powtarza się od 4 do 13 (włącznie).

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

Możemy również iterować tablice za pomocą for

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

for name in names
    puts name
end

Iteracja z indeksem

Czasami chcesz poznać pozycję ( indeks ) bieżącego elementu podczas iteracji po module wyliczającym. W tym celu Ruby udostępnia metodę with_index . Można go zastosować do wszystkich modułów wyliczających. Zasadniczo, dodając with_index do wyliczenia, można wyliczyć to wyliczenie. Indeks jest przekazywany do bloku jako drugi argument.

[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 ma opcjonalny argument - pierwszy indeks, który domyślnie ma wartość 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]

Istnieje specjalna metoda each_with_index . Jedyna różnica między nim a każdym z nich. Z each.with_index polega na tym, że nie można przekazać argumentu, więc pierwszy indeks ma wartość 0 cały czas.

[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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow