程式扎記: [ 範例代碼 ] Array's collect with index?

標籤

2014年10月29日 星期三

[ 範例代碼 ] Array's collect with index?

Source From Here 
Preface 
We know Array provides a useful API:collect/API:collect! to help use collect element from Array. For example, if I want to collect even number from an array: 
>> a = [1,2,3,4,5,6,7,8,9,10]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> a.collect{|i| i%2==0}
=> [false, true, false, true, false, true, false, true, false, true] # This is not what I want...Orz
>> a.collect{|i| i if i%2==0}.compact
=> [2, 4, 6, 8, 10] API:compact will help us to remove nil element inside array

But what if I need to use index of element as judge condition? For example, I have another array b with true/false to tell me if this element will be kept in collected array: 
>> b = Array.new(a.size, false)
=> [false, false, false, false, false, false, false, false, false, false]
>> b.map{|a| true if rand(2)>0}
=> [false, true, false, false, false, truetrue, false, false, false]
>> b.each_with_index do |v, i|; puts i if v; end
1
5
6
 # So here means only a[1], a[5] and a[6] will be collected!

How-To 
Fortunately, we have a Enumerator module to help on this case. Let's try it as below: 
>> require "enumerator"
=> true
>> a.to_enum(:each_with_index)
=> #
>> a.to_enum(:each_with_index).collect{|v,a| v if b[a]}.compact
=> [2, 6, 7]

AP:obj.to_enum(method = :each, *args) will create a new Enumerator which will enumerate by on calling method on obj

Supplement 
Stackoverflow - How to get a random number in Ruby?

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!