Ruby: Enumerator Chain
enumerable, ruby
Solution
Perhaps you need a `map` which you would like to apply only on the leafs:
module Enumerable
def nested_map &block
map{|e|
case e
when Enumerable
e.nested_map(&block)
else
block.call(e)
end
}
end
end
p [[1,2], [3,4]].nested_map(&:succ)
#=> [[2, 3], [4, 5]]
or a `map` which would apply only on `n`-th level of the nested structure.
module Enumerable
def deep_map level, &block
if level == 0
map(&block)
else
map{|e| e.deep_map(level - 1, &block)}
end
end
end
p [[1,2], [3,4]].deep_map(1, &:succ)
#=> [[2, 3], [4, 5]]
Problem
Initially I was going to do something like below: ``` arr = [[1,2],[3,4]] new_arr = arr.map do |sub_arr| sub_arr.map do |x| x+1 end end p new_arr ``` Output: ``` [[2,3],[4,5]] ``` But then I tried to short it by "chaining up" the enumerators: ``` arr.map.map{|x| x+1} ``` Then it gives error `to_ary method missing` I debugged it by ``` arr.each.each{|x| p x} ``` Output: ``` [1,2] [3,4] ``` ,which is the original array and only desected once. How can I chain two map/each enumerators so it will enumerator into 2 (or more) levels? Or it has to be in the block? Update: After some searching, apparently a chain `obj.Enumerator.Enumerator.Enumerator...` only enumerates the obj once, and only 1 level depth. In order to go deeper, block is required. I worked out simple code that would convert string to block(Proc/Lambda; similar to symbol to block but more of use; more like a functional syntax) so that block will be avoided. Someone has similar code `String#to_proc` but I couldn't find it, and the `x,y` thing in it does not appeal to my taste. I use `$0,$1,$2,...` Sample code (the previous example will be written as): ``` arr = [[1,2],[3,4]] new_arr = arr.map(&'[$0+1,$1+1]') p new_arr ``` I will push the original code to github later. You can use chat to contact me if you want to see it before that because I really procrastinate :)