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 van1
tot en met10
. Als we wilden dat het1
tot10
exclusief was, zouden we schrijven(1...10)
. -
.each
is een teller dieeach
element in het object.each
. In dit geval werkt het opeach
nummer in het bereik. -
{ |i| puts i.even? ? 'even' : 'odd' }
is het blok vooreach
instructie, die zelf verder kan worden uitgesplitst.-
|i|
dit betekent dat elk element in het bereik wordt vertegenwoordigd in het blok door de identificatiei
. -
puts
is een uitvoermethode in Ruby die na elke afdruk automatisch wordt afgebroken. (We kunnenprint
als we het automatische regeleinde niet willen) -
i.even?
controleert ofi
even 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]