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