举例讲解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