Our Daily Method #11: Hash#inv_multi

Geplaatst door Michiel de Mare di, 19 feb 2008 08:00:00 GMT

Hash has an invert-method, but it often happens that you’re dealing with a hash with arrays as values. Naturally, you don’t want arrays as keys – you want every element in the array to turn into a key, with an array of all original keys with that element as the value.

Simple example


{1 => [3,4]}.inv_multi
# => {3=>[1], 4=>[1]}

Complex example


{1 => [3,4,5,6], 2 => [3,4], 4 => 11}.inv_multi
# => {5=>[1], 11=>[4], 6=>[1], 3=>[1, 2], 4=>[1, 2]}
The method itself:

class Hash
  def inv_multi
    # there's inject! again. daily method #5
    inject!({}) do |h,(k,v)|  # Is this obvious? If not, say so!
      # this lambda binds h and k.
      l = lambda {|x| (h[x] ||= []) << k}
      if Array === v
        v.each(&l)
      else # value doesn't have to be an array
        l[v]
      end
    end
  end
end

Recommend Michiel de Mare

Geplaatst in , ,  | geen reacties

Reacties

(Laat url/e-mail achter »)

   Voorvertoning