yield/block question

K

Kenneth McDonald

This is something I know how to do in Python, but it's got me
flummoxed in Ruby--I still haven't fully gotten my head around the
Ruby way. ("yield" means something very different in Python and in Ruby.

Let's say I have a data structure consisting of nested Arrays and
numbers, for example [[1,2], 3, [[4]]]. I want to write an extension
to Array, "each_leaf", which takes a block that will be applied to
each number sequentially in that nested array. For example, if arr is
the given array, then

result = 0
arr.each_leaf {|n| result += n}

would end with result being equal to 1+2+3+4

Could anyone help out? Much appreciated.

Thanks,
Ken
 
M

Martin DeMello

This is something I know how to do in Python, but it's got me flummoxed in
Ruby--I still haven't fully gotten my head around the Ruby way. ("yield"
means something very different in Python and in Ruby.

Let's say I have a data structure consisting of nested Arrays and numbers,
for example [[1,2], 3, [[4]]]. I want to write an extension to Array,
"each_leaf", which takes a block that will be applied to each number
sequentially in that nested array. For example, if arr is the given array,
then

result = 0
arr.each_leaf {|n| result += n}

would end with result being equal to 1+2+3+4

Could anyone help out? Much appreciated.

array.flatten.each {|i| yield i}

martin
 
S

Serabe

What about this?

class Array
def each_leaf(&block)
each do |x|
case x
when Array: x.each_leaf &block
else block.call x
end
end
end
end

arr = [[1,2], 3, [[4]]]
result = 0
arr.each_leaf{|n| result += n}

puts result

Kind regards,

Serabe

P.D. Sorry for no more explanation, but I'm really tired (2:23 am right now).
 
K

Kenneth McDonald

Very elegant, with the drawback that it requires flattening a
potentially large array structure.
But that was carelessness in my lack of specifications. A nice
solution, thank you.

Ken


This is something I know how to do in Python, but it's got me
flummoxed in
Ruby--I still haven't fully gotten my head around the Ruby way.
("yield"
means something very different in Python and in Ruby.

Let's say I have a data structure consisting of nested Arrays and
numbers,
for example [[1,2], 3, [[4]]]. I want to write an extension to Array,
"each_leaf", which takes a block that will be applied to each number
sequentially in that nested array. For example, if arr is the given
array,
then

result = 0
arr.each_leaf {|n| result += n}

would end with result being equal to 1+2+3+4

Could anyone help out? Much appreciated.

array.flatten.each {|i| yield i}

martin
 
R

Robert Klemme

This can be generalized to Enumerable. Still a handicap is that this
does not gracefully deal with structures which are not cycle free.

Just some toying around:

module Enumerable
def each_leaf(cl = Object, &b)
each do |el|
case el
when String
yield el if cl === el
when Enumerable
el.each_leaf(cl, &b)
when cl
yield el
else
# ignore
end
end
end
end

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top