举例讲解Ruby中迭代器Iterator的用法
Iterator
定义
ARubyiteratorissimpleamethodthatcaninvokeablockofcode.
- Block一般是跟着method出现的,并且block中的代码不一定会执行
- 如果method中有yield,那么它的block中的代码会被执行
- Block可以接收参数,和返回value
deftwo_times
yield
yield
end
two_times{puts"Hello"}
#Hello
#Hello
deffib_up_to(max)
i1,i2=1.1
whilei1<=max
yieldi1
i1,i2=i2,i1+i2
end
end
fib_up_to(1000){|f|printf,""}
#1123581321345589144233377610987
上面代码中的yield之后的i1会作为parameter传入到block中,赋值给block的argumentf。
Block中可以有多个arguments.
常见的iterator
each
eachisprobablethesimplestiterator-allitdoesisyieldsuccessiveelementsofitscollection.
[1,3,5,7,9].each{|i|putsi}
#1
#3
#5
#7
#9
find
Abloclmayalsoreturnavaluetothemethod.Thevalueofthelastexpressionevaluatedintheblockispassedbacktothemethodasthevalueoftheyield.
classArray
deffind
eachdo|value|
returnvalueifyield(value)
end
end
end
[1,3,4,7,9].find{|v|V*V>30}#=>7
collect(alsoknownasmap)
Whichtakeseachelementfromthecollectionandpassesittotheblock.Theresultsreturnedbytheblockareusedtoconstructanewarray
["H","A","L"].collect{|x|x.succ}#=>["I","B","M"]
inject
Theinjectmethodletsyouaccumulateavalueacrossthemembersofacollection.
[1,3,5,7].inject{|sum,element|sum+element}#=>16
#sum=1,element=3
#sum=4,element=5
#sum=9,element=7
#sum=16
[1,3,5,6].inject{|product,element|product*element}#=>105
Ifinjectiscalledwithnoparameter,itusesthefirstelementofthecollectionsastheinitialvalueandstartstheiterationwiththesecondvalue.
上面代码的另一种简便写法:
[1,3,5,7].inject(:+)#=>16 [1,3,5,7]/inject(:*)#=>105
Iterator和I/O系统的交互
Iterators不仅仅能够访问Array和Hash中的数据,和可以和I/O系统交互
f=File.open("testfile")
f.eachdo|line|
puts"Thelineis:#{line}"
end
f.close
produces:
Thelineis:Thisislineone
Thelineis:Thisislinetwo
Thelineis:Thisislinethree