From: David Alan Black Date: 2000-12-17T06:53:51+09:00 Subject: [ruby-talk:7471] flatten_by(n) 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: 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. David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav