On Wed, 29 Nov 2000, Dave Thomas wrote: > David Alan Black <dblack / candle.superlink.net> writes: > > > I was wondering about a block form. I'm not sure exactly what it > > would do -- specifically, whether the results of the block would > > pertain to the keys or the values of the new hash. In other words, > > would it be this: > > > > each_with_index { |e,i| h[i] = yield(i, e) } > > > > or this: > > > > each_with_index { |e,i| h[yield(i, e)] = e } > > > > or > module Enumerable > def to_h(value = 1) > h = {} > if block_given? > each_with_index {|e,i| hk,hv = yield(e,i); h[hk] = hv } > else > each {|hv| h[hv] = value } > end > h > end > end Oh, ok :-) For what it's worth, here are the results of an attempt on my part to chart a path, method by method, from a very simple to_h approach to the more complex, useful ones (including use of blocks). The idea is to be as incremental as possible, defining later methods largely in terms of earlier ones (including an interleave method). My goal was to see how the principle of the array not "knowing" too much holds up, as things move beyond the level of an array just allowing itself to be interpreted as a hash and onto the level of things like accepting a value to set all the hash values to. (I couldn't see how that could *not* represent an array knowing too much, until I worked it through as shown below.) This stuff is not optimized or debugged, nor is it meant as a practical way of organizing or naming methods. It's more a sort of exploded/implemented model of this train of thought. module Enumerable # For convenience, adapted from the latest ruby-talk consensus def interleave(enum2) e1, e2, res = to_a.reverse, enum2.to_a.reverse, [] res.push e1.pop, e2.pop until e1.empty? or e2.empty? res + (e1 + e2) .reverse end # The simplest to_h: array elements are taken two at a time. # (Not even indices -- just elements.) def to_h_raw a = dup h = {} h[a.shift] = a.shift || nil until a.empty? h end # Now, building on that: # Indices as keys def to_h_ikeys (0...size) .interleave(self) .to_h_raw end # Elements as keys def to_h_ekeys to_h_ikeys .invert end # Elements as keys, values all set to value def to_h_v(value) interleave([].fill(value, 0...size)) .to_h_raw end # Block version def to_h_b (0...size) .map { |i| yield(at(i),i) } .flatten .to_h_raw end end ary = %w{one two three} ary.to_h_raw # => {"one"=>"two", "three"=>nil} ary.to_h_ikeys # => {0=>"one", 1=>"two", 2=>"three"} ary.to_h_ekeys # => {"one"=>0, "three"=>2, "two"=>1} ary.to_h_v true # => {"one"=>true, "three"=>true, "two"=>true} ary.to_h_b { |e,| [e.upcase, true] } # => {"ONE"=>true, "THREE"=>true, "TWO"=>true} __END__ David -- David Alan Black home: dblack / candle.superlink.net work: blackdav / shu.edu Web: http://pirate.shu.edu/~blackdav