David Alan Black <dblack / candle.superlink.net> wrote: > >Hello -- > >In honor of all the stuff about flattening in the thread ostensibly >about Perl (but happily not), I thought I'd share this, for the >possible reading/hacking pleasure of my fellow rubes: > > class Array > def flatten_by(n) > res = [] > return self if n < 1 > each do |e| > if e.is_a? Array > e.each do |ee| > res.push ee > res = res.flatten_by(n-1) > end > else > res.push e > end > end > res > end > end > > > a = [1, [2, [3], []], [5], [4, [[6]]]] > > a.flatten_by(0) => [1, [2, [3], []], [5], [4, [[6]]]] > a.flatten_by(1) => [1, 2, [3], [], 5, 4, [[6]]] > a.flatten_by(2) => [1, 2, 3, 5, 4, [6]] > a.flatten_by(3) => [1, 2, 3, 5, 4, 6] > > >And now.... (Ben, are you watching?) .... the grand test: Yup, watching... > class Array > def flat_map(&block) > map(&block) .flatten_by(1) > end > end > > [1,2,[3,4],5] .flat_map do |e| [e, "hello"] end > > => [1, "hello", 2, "hello", [3, 4], "hello", 5, "hello"] > > >It actually *could* be useful.... at least if, like me, you are >obsessed with turning arrays into hashes in every possible way: > > class Array > def to_h_all_true > Hash[*self.flat_map do |e| [e,true] end] > end > end > > [1, [2, [3], []], [5], [4, [[6]]]] .to_h_all_true > => {[5]=>true, 1=>true, [2, [3], []]=>true, [4, [[6]]]=>true} > > >Comments/optimizations/whatever welcome. Nice. Is there any reason that your flatten_by function takes a parameter? I would think it would be faster to have it just flatten once (don't do the recursive call). If someone wants to flatten 6 times, they can call it 6 times. I am away from my home box again, but something like this should work: class Array def flatten_once res = [] each do |e| if e.is_a? Array res += e else res.push e end end res end end Cheers, Ben _________________________________________________________________ Get your FREE download of MSN Explorer at http://explorer.msn.com