16
Iterator
Ruby’de başlıca döngü türleri while, until ve for döngüleridir. Ancak, Ruby
döngüler için programcılara, öteki dillerde olmayan bazı kolaylıklar sunar.
Bunlara iterator metotları denilir. Aslında iterator metotları’nın her birisi
bir döngüdür. Ama döngü sürecinde, istenen bazı eylemleri de yaparlar. Bu
işi, veri ambarında gezinen birisinin, ambardaki her nesneye elini değdirip,
onunla ilgili bir eylem yapması gibi düşünebiliriz. O nedenle, iterator
yerine, ses uyumunu da göz önüne alarak, gezer diyeceğiz.
Veri topluluklarını tutan nesnelere koleksiyon denilir. Ruby’de array
ve hash yapıları koleksiyon olarak nitelenir. Bir koleksiyonun her öğesine
uygulanan metotlara da gezer (iterator) denilir.
Gezerler, koleksiyonun bulunduğu veri ambarına girince, ambardaki
bütün öğeleri tek tek ziyaret ederler. Belli bir anda ziyaret etmekte oldukları öğeyi sunarlar. Dolayısıyla o öğe üzerinde istenen işlemler yapılabilir.
Tabii, yapılabilecek işler, söz konusu öğeye (nesneye) uygulanabilen eylemler olacaktır.
Ruby’de koleksiyon ambarlarını gezen iki önemli gezer (iterator) vardır: each ve collect. Ama bunların dışında da döngü kurmaya yarayan gezerler vardır:
3
times
upto
downto
step
202
BÖLÜM 16. ITERATOR
times döngüleri
Bir döngüde değişken (sayaç) kullanılabilir ya da kullanılmaz. Liste 16.1
döngüsünde sayaç değişkeni yoktur.
Liste 16.1.
1
# t i m e s döngüsünü k u l l a n ı y o r . Döngü d e ğ i ş k e n i yok .
4 . t i m e s do
puts " a "
end
Liste 16.2 i değişkenini sayaç olarak kullanıyor. Her adımda i sayacının
değeri 1 artıyor.
Liste 16.2.
1
2
7
5 . t i m e s do | i |
puts i
end
/∗ ∗
a
a
a
a
0
1
2
3
4
upto döngüleri
Bir döngü değişkenini istenen yerden başlatır, istenen sayıda artırarak istenen sayıya erişinceye kadar döngünün adımları tekrarlanır.
Program 16.1.
# upto
# 3 den 5 ’ e kadar .
3 . upto ( 5 ) do | x |
5
# Go up from x t o x + 2 .
x . upto ( x + 2 ) do | y |
# Display v a r i a b l e .
print y , " "
end
10
# End t h e l i n e .
p r i n t " \n "
end
203
2
/∗ ∗
3 4 5
4 5 6
5 6 7
∗/
downto döngüleri
Program 16.2.
# 5 ’ t e n 3 ’ e g e r i y e sa y
5 . downto ( 3 ) do | j |
# s a y a c ı yaz
puts j
5
end
4
/∗ ∗
5
4
3
∗/
step döngüleri
Program 16.3.
0 . step (12 , 3) { | x | p r i n t x , " " }
/∗ ∗
0 3 6 9 12
∗/
each döngüleri
each gezeri arrayler ve sözlükler üzerinde gezer. Gezdiği array ambarının
ya da sözlük ambarının her öğesini ziyaret anında verir. Sözdizimi şöyledir:
Liste 16.3.
2
k o l e k s i y o n . each do | v a r i a b l e |
code
end
Örnek:
Program 16.4.
204
2
1
6
BÖLÜM 16. ITERATOR
ary = [ 1 , 2 , 3 , 4 , 5 ]
a r y . each do | i |
puts i
end
/∗ ∗
Çıktı :
1
2
3
4
5
collect döngüleri
collect gezgini içine girdiği ambardaki bütün öğeleri birden verir. Sözdizimi
şöyledir:
Liste 16.4.
collection = collection . collect
Bir koleksiyon ister array ister hash yapısında olsun, collect metodu onun
bütün öğelerini birden verir. Örneğin,
Program 16.5.
#! / u s r / b i n / ruby
4
4
a = [1 ,2 ,3 ,4 ,5]
b = Array . new
b = a. collect
puts b
/∗ ∗
Çıktı :
1
2
3
4
5
16.0.1
clone döngüleri
clone metodu bir arrayi başka bir arraye kopya eder. Kopyayı aynen yapabileceği gibi, belirli bir kurala uyan değişiklikleri kopya üzerinde de yapabilir.
Program 16.6.
205
#! / u s r / b i n / ruby
3
5
a = [1 ,2 ,3 ,4 ,5]
b = a . c o l l e c t { | x | 10∗ x}
puts b
/∗ ∗
Çıktı :
10
20
30
40
50
times kullanma
Program 16.7.
#! / u s r / b i n / ruby
3
8
2
7
cevizler = nil
3 . my_times do | i |
c e v i z l e r = i +1
p u t s "#{ c a v i l l e r } p o t a t o "
end
puts c a v i l l e r + 1
/∗ ∗
Çıktı :
10
20
30
40
50
yield deyimi
yield ile kullanıcı kendi isteklerini tanımlayabilir. Aşağıdaki örnekteki ekle
metodu her adımda 3 artıyor.
Program 16.8.
#e n c o d i n g u t f −8
3
8
d e f e k l e 3 (max)
i = 0
w h i l e i <= max
yield i
i += 3
end
end
206
BÖLÜM 16. ITERATOR
Program 16.9.
1
5
#e n c o d i n g u t f −8
# 20 ’ ye kadar yaz
a d d t h r e e ( 2 0 ) do | n |
puts n
end
/∗ ∗
0
3
6
9
12
15
18
∗/
16.0.2
Başka Kullanışlı Gezginler
select : Blokta koşulu sağlayan bütün öğeleri verir.
reject : Koşulu sağlayan bloklar için bütün öğeleri verir.
collect (alias map): Blokta istenenleri sağlayan öğelerden oluşan yeni
bir array yarrratır.
detect (alias find) : Arrayin koşulu sağlayan tek bir öğesini verir; arrayin bütün öğelerini değil.
Bloktaki koşulu sağlayan ilk öğeyi verir.
inject : Yığın yapar.
inject
Program 16.10.
1
6
3
#! / u s r / b i n / ruby
@@@ruby
c l a s s Array
d e f sum
i n j e c t ( 0 ) { | t , n | t + n}
end
end
/∗ ∗
[ 1 , 2 , 3 ] . sum #=> 6
∗/
207
yield
Program 16.11.
2
7
3
#! / u s r / b i n / ruby
def katla
yield
yield
end
k a t l a { puts " Aydınlık günlere ! . . " }
/∗ ∗
Aydınlık günlere ! . .
Aydınlık günlere ! . .
∗/
Program 16.12.
1
6
#! / u s r / b i n / ruby
d e f ad
y i e l d ( " Altan " )
y i e l d ( " Aren " )
y i e l d ( " Deniz " )
end
ad do | ad |
p u t s " Merhaba " + ad + " , N a s ı l s ı n ? "
end
5
/∗ ∗
Merhaba Altan , N a s ı l s ı n ?
Merhaba Aren , N a s ı l s ı n ?
Merhaba Deniz , N a s ı l s ı n ?
∗/
select
Ambardan koşulu sağlayan öğeleri seçer.
Program 16.13.
a = [1 ,2 ,3 ,4]
a . s e l e c t { | n | n > 2}
3
/∗ ∗
3 ,4
∗/
208
BÖLÜM 16. ITERATOR
reject
Ambardan koşulu sağlayan öğeleri dışlar, ötekileri seçer.
Program 16.14.
2
a = [1 ,2 ,3 ,4]
a . r e j e c t { | n | n > 2}
3
/∗ ∗
1 ,2
∗/
collect
Ambardan her öğe için, verilen koşula uyan yeni öğeler üretir. Aşağıdaki
program a= [1,2,3,4] arrayi yerine=> [1, 4, 9, 16] arrayini üretir.
Program 16.15.
2
a = [1 ,2 ,3 ,4]
a . c o l l e c t { | n | n∗n}
3
/∗ ∗
[1 , 4 , 9 , 16]
∗/
inject
Arrayin bütün öğelerinin toplamını verir.
Program 16.16.
2
a = [1 ,2 ,3 ,4]
a . i n j e c t ( 1 0 ) { | acc , n | a c c + n}
3
/∗ ∗
10
∗/
Bazan arrayin her öğesini kendisine ekleyerek yeni bir array yaratmak
isteyebiliriz:
Program 16.17.
2
a = [1 ,2 ,3 ,4]
a . i n j e c t ( [ ] ) { | acc , n | a c c << n+n}
3
/∗ ∗
=> [ 2 , 4 , 6 , 8 ]
∗/
16.1. ALIŞTIRMALAR
209
detect
Ambarda bir öğeyi bulur.
Program 16.18.
2
a = [1 ,2 ,3 ,4]
a . d e t e c t { | n | n == 3}
3
/∗ ∗
=> 3
∗/
16.1
Alıştırmalar
for döngüsü
Program 16.19.
2
1
#! / u s r / b i n / ruby
f o r i i n [ 1 , 2 , 3 ] do
puts ( i )
end
/∗ ∗
1
2
3
∗/
Yukarıdaki for döngüsünü each gezerini kullanarak şöyle yazabiliriz:
each gezeri
Program 16.20.
#! / u s r / b i n / ruby
[ 1 , 2 , 3 ] . each do | i |
puts ( i )
end
1
/∗ ∗
1
2
3
∗/
210
BÖLÜM 16. ITERATOR
for döngüsü
Program 16.21.
#! / u s r / b i n / ruby
5
for
k e n t i n [ " ankara " , " i z m i r " , " k a y s e r i " ] do
puts ( s )
end
5
/∗ ∗
ankara
izmir
kayseri
∗/
Program 16.22.
#! / u s r / b i n / ruby
5
for
k e n t i n [ " ankara " , " i z m i r " , " k a y s e r i " ] do
puts ( s )
end
5
/∗ ∗
ankara
izmir
kayseri
∗/
Program 16.23, each gezeri lie şöyle yazılabilir:
each gezeri
Program 16.23.
#! / u s r / b i n / ruby
5
[ " ankara " , " i z m i r " , " k a y s e r i " ] . each do | k e n t |
puts ( kent )
end
5
/∗ ∗
ankara
izmir
kayseri
∗/
Bazan döngünün her her dyimini ayrı bir satıra yazmak yerine, hepsini tek
satıra yazabiliriz:
16.1. ALIŞTIRMALAR
211
tek satırlık for döngüsü
Program 16.24.
#! / u s r / b i n / ruby
# t e k s a t ı r l ı k f o r döngüsü
f o r x i n [ 3 , " ankara " , [ 4 , 5 , 6 ] , f a l s e ] do p u t s ( x ) end
2
/∗ ∗
=> [ 3 , " ankara " , [ 4 , 5 , 6 ] , f a l s e ]
∗/
tek satırlık each gezeri
Program 16.25.
2
2
#! / u s r / b i n / ruby
# t e k s a t ı r l ı k each g e z e r i
[ 3 , " ankara " , [ 4 , 5 , 6 ] , f a l s e ] . each
do | x | p u t s ( x ) end
/∗ ∗
=> [ 3 , " ankara " , [ 4 , 5 , 6 ] , f a l s e ]
∗/
Çok satırlı döngülerde bloklardan önce do anahtar sözcüğü konulmayabilir,
ama tek satırlı döngülerde do konulması zorunludur.
Ruby’de blokları sınır çizmek için farklı yöntemler uygulanabilir. Örneğin,
do_end bloku
Program 16.26.
2
1
6
[ ’ a ’ , [ 1 , 3 , 5 ] , 7 , 9 ] . each do
|x,y,z|
p u t s ( "#{x } , #{x } , #{x} " )
end
/∗ ∗
a, a,
1, 1,
7, 7,
9, 9,
∗/
a
1
7
9
212
BÖLÜM 16. ITERATOR
{ } bloku
Program 16.27.
4
1
6
[ ’ a ’ , [ 1 , 3 , 5 ] , 7 , 9 ] . each {
|x,y,z|
p u t s ( "#{x } , #{x } , #{x} " )
}
/∗ ∗
a, a,
1, 1,
7, 7,
9, 9,
∗/
a
1
7
9
Blok açarken ister do ister { parantez açmayı kullanıyor olalım, bunlar
daima each ile aynı satırda olmalıdır.
16.2
Alıştırmalar
1.
Program 16.28.
3 . t i m e s do
p r i n t " Hey ! "
end
2
/∗ ∗
Ho ! Ho ! Ho !
∗/
Program 16.29.
2
0 . upto ( 9 ) do | x |
print x , " "
end
2
/∗ ∗
0 1 2 3 4 5 6 7 8 9
∗/
Program 16.30.
[ 1 , 1 , 2 , 3 , 5 ] . each { | v a l | p r i n t v a l , " " }
/∗ ∗
1 1 2 3 5
∗/
16.2. ALIŞTIRMALAR
2
1
# Use a tim es −l o o p .
4 . t i m e s do
puts " a "
end
# Use a t i m e s i t e r a t o r with an i t e r a t i o n v a r i a b l e .
5 . t i m e s do | i |
puts i
end
Program 16.31.
1
6
11
2
7
12
#Program t h a t u s e s s t e p : Ruby
# I n c r e m e n t from 0 t o 1 0 , by 2 each time .
# . . . Name t h e i t e r a t i o n v a r i a b l e " v " .
0 . s t e p ( 1 0 , 2 ) do | v |
puts v
end
# Decrement from 12 t o 6 , by −2 each time .
# . . . Name t h e i t e r a t i o n v a r i a b l e " i t e r " .
1 2 . s t e p ( 6 , −2) do | i t e r |
puts i t e r
end
/∗ ∗
0
2
4
6
8
10
12
10
8
6
∗/
0 2 4 6 8 10 12 10 8 6
Program 16.32.
3
c l a s s String
d e f reverse_each_word
s e l f . s p l i t . c o l l e c t { | word | word . r e v e r s e }
end
end
Program 16.33.
213
214
BÖLÜM 16. ITERATOR
5
c l a s s String
d e f each_word
s e l f . s p l i t . each { | word |
end
end
y i e l d word }
Program 16.34.
" This i s a v e r y s h o r t sample s t r i n g " . each_word do | word |
word . r e v e r s e . u p c a s e
end
Ruby on Rails’de Kullanılan İterator Metotları
Program 16.35.
2
7
12
[ 1 , 2 , 3 ] . each { }
=> [ 1 , 2 , 3 ]
[ 1 , n i l , n i l , 2 , 3 , n i l ] . compact { } => [ 1 , 2 , 3 ]
[ 1 , 2 , 3 ] . d e l e t e _ i f { | x | x >= 3 }
=> [ 1 , 2 ]
[1 , 2 , 3]. collect { | x | x + 1 }
=> [ 2 , 3 , 4 ]
[ 1 , 2 , 3 ] . f i n d _ a l l { | x | x % 2 == 1 } => [ 1 , 3 ]
[ 1 , 2 , 3 ] . r e j e c t { | x | x % 2 == 1 }
=> [ 2 ]
[2 , 5 , 1 , 0 , 7]. sort
=> [ 0 , 1 , 2 , 5 , 7 ]
[ 2 , 5 , 1 , 0 , 7 ] . max
=> 7
[1 , [2 , 3 ] ] . flatten
=> [ 1 , 2 , 3 ]
[ 1 , 2 , 3 ] . empty ?
=> f a l s e
[ ] . empty ?
=> t r u e
[0 , 5 , 9 ] . length
=> 3
[1 , 2 , 3 ] . include ?(2)
=> t r u e
[1 , 2 , 3 ] . include ?(16)
=> f a l s e
[1 , 2 , 3]. reverse
=> [ 3 , 2 , 1 ]
Download

Iterator