Injecting Hash (with Ruby)

Angelegt von suung Sat, 28 Aug 2010 00:19:00 GMT

I had this article open about Ruby's Enumerable#inject which you can use, to build a Hash , (or) which looks like this

 

{

   :a => :b, :c => :d

}


for those not used to thinking in data structures, this is something like a index, where a key points to a entry in the directory / telephone book, whatever. :)

 

The Article talks about this problem:

# you have an array, that looks like this

[[:key, :value], [:other_key, :other_value]]

this is realistic, e.g. when you parse a query, looking like this:

"key/value/other_key/other_value/,,,,"

 

the code to do it looks like this:

[[:key, :value], [:other_key, :other_value]].inject({}) {|result,element| result[element.first] = element.last}

what it does is:

* take the array (the list with the two other two-entry - arrays inside

* go through it

* return(ing) a Hash

* and add the second element (the last) as the value for the first element to that hash

so, ok, that's pretty cool, you will see this often.

 

Later, still having open that article, i stumbled upon a different problem:


Often you want to enable a method to accept some arguments, or an array of arguments or a hash of arguments, where you pass options to that argument.

This may look like this

def my_function arg

   if arg.kind_of?(Symbol)

      # do something default

  elsif arg.kind_of?(Array)
      arg.each do |a|

         # do something recursive, iterate through the array and call the same or another function with the entry as arg(.to_sym)    

    end

 elsif arg.kind_of?(Hash)

   arg.each do |k,v|
     # do the same as for a array, but pass the value to the the function call for the key
     do_something(k,v)

   end
end

hope you got the idea.

 

Ok, let's assume our do_something method looks like this

def do_something arg, options={}

    ....

end

in this case, options can handle the optional value of our hash and is never nil

Now because i am lazy, i wanted to improve that case a little bit and thought:

Hey, lets (in this special case) just transform the Array (in case it is one ) to an Hash like this

{:a => nil, :b => nil}

so i could easliy use the same behaviour in the method and don't need to different methods to handle either the Array or the Hash

 

with inject, it works like this:

 

[:a,:b,:c].inject({}) {|result, element| result[element] = nil; result}

 

the trick is, to force the return of result at the end

Trackbacks

Verwenden Sie den folgenden Link zur Rückverlinkung von Ihrer eigenen Seite:
http://praktikanten.brueckenschlaeger.org/trackbacks?article_id=227

Leave a comment

Comments