Ruby Language
herhaling
Zoeken…
Elk
Ruby heeft veel soorten tellers, maar de eerste en meest eenvoudige soort om mee te beginnen is each . We zullen even of odd afdrukken voor elk nummer tussen 1 en 10 om te laten zien hoe each werkt.
In principe zijn er twee manieren om zogenaamde blocks te passeren. Een block is een stuk code dat wordt doorgegeven en dat wordt uitgevoerd met de methode die wordt aangeroepen. Bij each methode wordt een block dat elk element van de verzameling objecten oproept waarnaar het werd opgeroepen.
Er zijn twee manieren om een blok aan een methode door te geven:
Methode 1: Inline
(1..10).each { |i| puts i.even? ? 'even' : 'odd' }
Dit is een zeer gecomprimeerde en robijnrode manier om dit op te lossen. Laten we dit stuk voor stuk afbreken.
-
(1..10)is een bereik van1tot en met10. Als we wilden dat het1tot10exclusief was, zouden we schrijven(1...10). -
.eachis een teller dieeachelement in het object.each. In dit geval werkt het opeachnummer in het bereik. -
{ |i| puts i.even? ? 'even' : 'odd' }is het blok vooreachinstructie, die zelf verder kan worden uitgesplitst.-
|i|dit betekent dat elk element in het bereik wordt vertegenwoordigd in het blok door de identificatiei. -
putsis een uitvoermethode in Ruby die na elke afdruk automatisch wordt afgebroken. (We kunnenprintals we het automatische regeleinde niet willen) -
i.even?controleert ofieven is. We hadden ooki % 2 == 0; het heeft echter de voorkeur om ingebouwde methoden te gebruiken. -
? "even" : "odd"dit is de ternaire operator van ruby. De manier waarop een ternaire operator is opgebouwd, isexpression ? a : b. Dit is een afkorting voor
if expression a else b end
-
Voor code langer dan één regel moet het block worden doorgegeven als een multiline block .
Methode 2: Multiline
(1..10).each do |i|
if i.even?
puts 'even'
else
puts 'odd'
end
end
In een multiline block het do vervangt het haakje openen en end vervangt de sluithaak van de inline stijl.
Ruby ondersteunt ook reverse_each. Het zal de array achteruit doorlopen.
@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"
Implementatie in een klas
Enumerable is de meest populaire module in Ruby. Het doel is om u te voorzien van iterabele methoden zoals map , select , reduce , enz. Klassen die Enumerable zijn Array , Hash , Range . Om het te gebruiken, moet u include Enumerable en each implementeren.
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]
Kaart
Retourneert het gewijzigde object, maar het oorspronkelijke object blijft zoals het was. Bijvoorbeeld:
arr = [1, 2, 3]
arr.map { |i| i + 1 } # => [2, 3, 4]
arr # => [1, 2, 3]
map! wijzigt het oorspronkelijke object:
arr = [1, 2, 3]
arr.map! { |i| i + 1 } # => [2, 3, 4]
arr # => [2, 3, 4]
Opmerking: u kunt collect ook gebruiken collect hetzelfde te doen.
Herhalen over complexe objecten
arrays
U kunt herhalen over geneste arrays:
[[1, 2], [3, 4]].each { |(a, b)| p "a: #{ a }", "b: #{ b }" }
De volgende syntaxis is ook toegestaan:
[[1, 2], [3, 4]].each { |a, b| "a: #{ a }", "b: #{ b }" }
Zal produceren:
"a: 1"
"b: 2"
"a: 3"
"b: 4"
hashes
U kunt meerdere sleutel / waarde-paren herhalen:
{a: 1, b: 2, c: 3}.each { |pair| p "pair: #{ pair }" }
Zal produceren:
"pair: [:a, 1]"
"pair: [:b, 2]"
"pair: [:c, 3]"
U kunt toetsen en waarden tegelijkertijd herhalen:
{a: 1, b: 2, c: 3}.each { |(k, v)| p "k: #{ k }", "v: #{ k }" }
Zal produceren:
"k: a"
"v: a"
"k: b"
"v: b"
"k: c"
"v: c"
Voor iterator
Dit wordt herhaald van 4 tot 13 (inclusief).
for i in 4..13
puts "this is #{i}.th number"
end
We kunnen ook herhalen over arrays die gebruiken voor
names = ['Siva', 'Charan', 'Naresh', 'Manish']
for name in names
puts name
end
Iteratie met index
Soms wilt u de positie ( index ) van het huidige element weten terwijl u over een teller loopt. Voor dat doel biedt Ruby de methode with_index . Het kan worden toegepast op alle tellers. Kortom, door with_index te voegen aan een opsomming, kunt u die opsomming opsommen. Index wordt als tweede argument aan een blok doorgegeven.
[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 heeft een optioneel argument - de eerste index die standaard 0 is:
[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]
Er is een specifieke methode each_with_index . Het enige verschil tussen het en each.with_index is dat je daar geen argument aan kunt doorgeven, dus de eerste index is altijd 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]