Prev: A little help needed
Next: ANN: Sequel 3.10.0 Released
From: Ryan Davis on 3 Apr 2010 05:42 On Apr 2, 2010, at 16:28 , Rick DeNatale wrote: > [[*(1..20)], 25, [*(30..46)]].flatten.each {|n| p n} or: class Range alias :to_a :to_ary end >> [1..20, 25, 30..46].flatten => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46] I think that's a lot prettier... seems safe to me :D
From: Colin Bartlett on 3 Apr 2010 07:50 On Fri, Apr 2, 2010 at 11:33 PM, Roger Pack <rogerpack2005(a)gmail.com> wrote: > David Springer wrote: >> Will this work: >> [1..20,30..46].each{|r| r.each {|n| p n}} > > Yeah that works. > I guess if I need individual values in there (like 25) I can do > [1..20, 25..25, 30..46].each{|r| r.each {|n| p n}} Given the solutions proposed, in suggesting this I have a feeling I may well be missing something, but since I might learn something: why not write a method (and maybe add it to Array) like: def each_element_or_range_element( arr ) arr.each do |er| if er.kind_of?( Range ) then er.each { |e| yield e } else yield er end end end aa = [ 1..2, 355, 3..4, 113, 2.5 , 3.5..5.5 ] each_element_or_range_element(aa) { |e| print " #{e}" } 1 2 355 3 4 113 2.5 TypeError: can't iterate from Float
From: Intransition on 3 Apr 2010 08:22 On Apr 3, 5:42 am, Ryan Davis <ryand-r...(a)zenspider.com> wrote: > On Apr 2, 2010, at 16:28 , Rick DeNatale wrote: > > > [[*(1..20)], 25, [*(30..46)]].flatten.each {|n| p n} > > or: > > class Range > alias :to_a :to_ary > end > > >> [1..20, 25, 30..46].flatten > > => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46] > > I think that's a lot prettier... seems safe to me :D I can't think of any reason that it wouldn't be safe --and if it is then it's a very nice solution. But Ryan did you use the :D emoticon to suggest that it really was unsafe? In any case, to avoid the large footprint of using flatten you could try something like module Enumerable def visit each do |n| if Enumerable===n n.each{ |*s| yield(*s) } else yield(n) end end end end [1..20, 25, 30..46].visit{ |n| p n } *I did not test this code, so it may need tweaking. But you get the idea.
From: Robert Klemme on 3 Apr 2010 09:21 On 04/03/2010 04:14 AM, Gary Wright wrote: > On Apr 2, 2010, at 10:01 PM, Rick DeNatale wrote: > >> On Fri, Apr 2, 2010 at 8:20 PM, Tomo Kazahaya <tomonacci(a)gmail.com> wrote: >>> [*1..20, 25, *30..46] >> I'm afraid that that give a syntax error in both 1.8.7 and 1.9 > > I only have 1.9.0 handy, but did something change when I wasn't looking: > > $ ruby1.9 -v > ruby 1.9.0 (2008-07-25 revision 18217) [i686-darwin9] > $ ruby1.9 -e 'p [*1..20, 25, *30..46]' > [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46] I don't think so. robert(a)fussel:~$ ruby19 --version ruby 1.9.1p376 (2009-12-07 revision 26041) [i686-linux] robert(a)fussel:~$ ruby19 -e 'p [1,2,*10..15,345]' [1, 2, 10, 11, 12, 13, 14, 15, 345] Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Robert Klemme on 3 Apr 2010 09:29
On 04/03/2010 01:50 PM, Colin Bartlett wrote: > On Fri, Apr 2, 2010 at 11:33 PM, Roger Pack <rogerpack2005(a)gmail.com> wrote: >> David Springer wrote: >>> Will this work: >>> [1..20,30..46].each{|r| r.each {|n| p n}} >> Yeah that works. >> I guess if I need individual values in there (like 25) I can do >> [1..20, 25..25, 30..46].each{|r| r.each {|n| p n}} > > Given the solutions proposed, in suggesting this I have a feeling > I may well be missing something, but since I might learn something: > why not write a method (and maybe add it to Array) like: > > def each_element_or_range_element( arr ) > arr.each do |er| > if er.kind_of?( Range ) then er.each { |e| yield e } > else yield er > end > end > end Here's my general purpose solution: module Enumerable def each_flat(levels, &b) each do |x| if levels > 1 && Enumerable === x x.each_flat(levels - 1, &b) else b[x] end end self end end a = [ 1, 2, 10..15, 3, 4, [99,100,101,["no more"]], ] a.each_flat 2 do |x| p x end Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/ |