Ruby Language
Iterazione
Ricerca…
Ogni
Ruby ha molti tipi di enumeratori ma il primo e più semplice tipo di enumeratore da cui iniziare è each
. Faremo stampare even
o odd
per ogni numero compreso tra 1
e 10
per mostrare come each
opera.
Fondamentalmente ci sono due modi per passare i cosiddetti blocks
. Un block
è un pezzo di codice che viene passato che verrà eseguito dal metodo chiamato. each
metodo prende un block
che chiama per ogni elemento della collezione di oggetti su cui è stato chiamato.
Esistono due modi per passare un blocco a un metodo:
Metodo 1: in linea
(1..10).each { |i| puts i.even? ? 'even' : 'odd' }
Questo è un modo molto compresso e rubino per risolvere questo. Rompiamo questo pezzo per pezzo.
-
(1..10)
è un intervallo compreso tra1
e10
inclusi. Se volessimo che fosse da1
a10
esclusivi, scriveremmo(1...10)
. -
.each
è un enumeratore che enumera sueach
elemento nell'oggetto su cui sta agendo. In questo caso, agisce sueach
numero nell'intervallo. -
{ |i| puts i.even? ? 'even' : 'odd' }
è il blocco pereach
istruzione, che a sua volta può essere ulteriormente suddivisa.-
|i|
questo significa che ogni elemento nell'intervallo è rappresentato all'interno del blocco dall'identificatorei
. -
puts
è un metodo di output in Ruby che ha un'interruzione di riga automatica ogni volta che viene stampata. (Possiamo usare laprint
se non vogliamo l'interruzione automatica della linea) -
i.even?
controlla sei
è pari. Avremmo potuto usare anchei % 2 == 0
; tuttavia, è preferibile utilizzare metodi incorporati. -
? "even" : "odd"
questo è l'operatore ternario di Ruby. Il modo in cui un operatore ternario è costruito èexpression ? a : b
. Questo è l'abbreviazione di
if expression a else b end
-
Per il codice più lungo di una riga, il block
deve essere passato come un multiline block
.
Metodo 2: multilinea
(1..10).each do |i| if i.even? puts 'even' else puts 'odd' end end
In un multiline block
il do
sostituisce la parentesi aperta e end
sostituisce la parentesi chiusa dallo stile in inline
.
Ruby supporta anche reverse_each. Ripeterà l'array all'indietro.
@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"
Implementazione in una classe
Enumerable
è il modulo più popolare in Ruby. Il suo scopo è quello di fornire metodi iterabili come la map
, select
, reduce
, ecc. Le classi che usano Enumerable
includono Array
, Hash
, Range
. Per usarlo, devi include Enumerable
e implementare 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]
Carta geografica
Restituisce l'oggetto modificato, ma l'oggetto originale rimane com'era. Per esempio:
arr = [1, 2, 3]
arr.map { |i| i + 1 } # => [2, 3, 4]
arr # => [1, 2, 3]
map!
cambia l'oggetto originale:
arr = [1, 2, 3]
arr.map! { |i| i + 1 } # => [2, 3, 4]
arr # => [2, 3, 4]
Nota: puoi anche utilizzare collect
per fare la stessa cosa.
Iterare su oggetti complessi
Array
È possibile eseguire iterazioni su array annidati:
[[1, 2], [3, 4]].each { |(a, b)| p "a: #{ a }", "b: #{ b }" }
La seguente sintassi è consentita anche:
[[1, 2], [3, 4]].each { |a, b| "a: #{ a }", "b: #{ b }" }
Produrrà:
"a: 1"
"b: 2"
"a: 3"
"b: 4"
hash
Puoi eseguire l'iterazione su coppie chiave-valore:
{a: 1, b: 2, c: 3}.each { |pair| p "pair: #{ pair }" }
Produrrà:
"pair: [:a, 1]"
"pair: [:b, 2]"
"pair: [:c, 3]"
Puoi scorrere simultaneamente su chiavi e valori:
{a: 1, b: 2, c: 3}.each { |(k, v)| p "k: #{ k }", "v: #{ k }" }
Produrrà:
"k: a"
"v: a"
"k: b"
"v: b"
"k: c"
"v: c"
Per l'iteratore
Questo itera da 4 a 13 (inclusi).
for i in 4..13
puts "this is #{i}.th number"
end
Possiamo anche eseguire iterazioni su array usando for
names = ['Siva', 'Charan', 'Naresh', 'Manish']
for name in names
puts name
end
Iterazione con indice
A volte si desidera conoscere la posizione ( indice ) dell'elemento corrente mentre si esegue l'iterazione su un enumeratore. A tale scopo, Ruby fornisce il metodo with_index
. Può essere applicato a tutti gli enumeratori. Fondamentalmente, aggiungendo with_index
a un'enumerazione, è possibile enumerare tale enumerazione. L'indice viene passato a un blocco come secondo argomento.
[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
ha un argomento opzionale - il primo indice che è 0
per impostazione predefinita:
[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]
Esiste un metodo specifico each_with_index
. L'unica differenza tra esso e each.with_index
è che non puoi passare un argomento a questo, quindi il primo indice è sempre 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]