1.4.1.5. fejezet, Ciklusok és léptetők
Ciklusokból is sokféle van, ment több másik Ruby formulából. A megszokott for..do ciklust is sokféleképp írhatjuk le:
for i in [1,2,3] do puts( i ) end for s in ['one','two','three'] puts( s ) end for s in 1..3 puts( s ) end for s in ['one','two','three'] do puts( s ) end [1,2,3].each do |i| puts( i ) end (1..3).each do |s| puts(s) end for i in (1..10) do puts( i ) end
Többdimenziós tömbökre is van for iterátor, erre már láttunk is korábban példát
for (a,b,c,d) in multiarr print("a=#{a}, b=#{b}, c=#{c}, d=#{d}\n" ) end multiarr.each do |a,b,c,d| print("a=#{a}, b=#{b}, c=#{c}, d=#{d}\n" ) end
While ciklusok
Az előbb elől-tesztelő ciklusokat láthattunk. Itt következnek az elől- és hátul-tesztelő ciklusok, a while és az until. Mindkettő használható elől- és hátul-teszteléshez.
begin sleep snore end while tired while tired do sleep end while tired sleep end sleep while tired
Ugyanez until használatával:
i = 0 until i == 10 do puts(i) i+=1 end begin puts(i) end until i == 10 until i == arr.length puts(arr[i]) i +=1 end
Talán így egyszerűbb különbséget tenni:
while i < arr.length puts(arr[i]) i += 1 end until i == arr.length puts(arr[i]) i +=1 end
Egy különösen összetett és bonyolult módja az iterációnak:
i=0 loop { puts(arr[i]) i+=1 if (i == arr.length) then break end }
Megszámlálhatóság
Az Enumerable modul korábban bekerült már az Array osztályba, így a tömbelemeknek van egy speciális lekérdezése: include?, és néhány hasznos metódusa:
arr = [1,2,3,4,5] y = arr.collect{ |i| i } #=> y = [1, 2, 3, 4] z = arr.collect{ |i| i * i } #=> z = [1, 4, 9, 16, 25] arr.include?( 3 ) #=> true arr.include?( 6 ) #=> false
A tömb értékek minimuma és maximuma is könnyen megállapítható:
arr.min #=> 1 arr.max #=> 5
A Hash táblánál minden szöveges kulcs mező értékeit ASCII betűkké alakít a fenti két függvény, és ezek adják a szám szerinti minimum és maximum értéket. Az alábbi két metódussal felülírható ez az összehasonlítás:
h.min{ |a,b| a[0].length <=> b[0].length } h.max{|a,b| a[0].length <=> b[0].length }
Tehát a következő Hash táblát:
{„one‟=>‟for sorrow‟, „two‟=>‟for joy‟}
Így kapja meg a két függvény:
a = [„one‟,‟for sorrow‟] b = [„two‟,‟for joy‟]
Mindkettőnek a 0. indexe a kulcs index. Ennek a hosszát hasonlítja össze. Ha az értéket szeretnénk összehasonlítani, csináljuk így:
p( h.min{|a,b| a[1].length <=> b[1].length } ) p( h.max{|a,b| a[1].length <=> b[1].length } )
Ha a szerint szeretnénk összehasonlítani, ami szerint kimondják angolul, akkor csinálunk egy tömböt a kimondásnak megfelelő sorrendű tartalommal:
str_arr=['one','two','three','four','five','six','seven']
és ezt használjuk fel az összehasonlításhoz:
h.min{|a,b| str_arr.index(a[0]) <=> str_arr.index(b[0])} #=> ["one", "for sorrow"] h.max{|a,b| str_arr.index(a[0]) <=> str_arr.index(b[0])} #=> ["seven", "for a secret never to be told"]
Mint korábban írtam, az Enumerable modul tartalmazza a min,max,collect metódusokat. Ha saját osztályban szeretnénk csinálni ilyen iterációt, be kell emelni az Enumerable osztályt.
class MyCollection include Enumerable def initialize( someItems ) @items = someItems end def each @items.each{ |i| yield( i ) } end end things = MyCollection.new(['x','yz','defgh','ij','klmno']) p( things.min ) #=> "defgh" p( things.max ) #=> "yz" p( things.collect{ |i| i.upcase } ) #=> ["X", "YZ", "DEFGH", "IJ", "KLMNO"]
Ha másképp szeretnénk összehasonlítani, egyszerűen írjuk felül a metódusokat:
def min @items.to_a.min{|a,b| a.length <=> b.length } end def max @items.to_a.max{|a,b| a.length <=> b.length } end
A yield metódus a kapott blokkot a paramétereket felhasználva végrehajtja, így pl. a min, max, vagy collate blokkokat. Ezért az each metódust így definiáljuk:
def each @items.each{ |i| yield( i ) } end
A yield metódus így is szemléltethető:
def test puts "You are in the method" yield puts "You are again back to the method" yield end test {puts "You are in the block"}
Kimenet:
You are in the method You are in the block You are again back to the method You are in the block
Paramétereket is átadhatunk a yield-nek.
def test yield 5 puts "You are in the method test" yield 100 end test {|i| puts "You are in the block #{i}"}
Eredménye:
You are in the block 5 You are in the method test You are in the block 100
Ha több paramétert is átadunk a yield-nek, vesszővel elválasztva hívjuk meg.
yield a, b
Majd a test blokk meghívását is módosítjuk:
test {|a, b| statement}
- A hozzászóláshoz be kell jelentkezni