Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a hash in a conditional way

I am using Ruby on Rails 3.0.10 and I would like to build an hash key\value pairs in a conditional way. That is, I would like to add a key and its related value if a condition is matched:

hash = {
  :key1 => value1,
  :key2 => value2, # This key2\value2 pair should be added only 'if condition' is 'true'
  :key3 => value3,
  ...
}

How can I do that and keep a "good" readability for the code? Am I "forced" to use the merge method?

like image 621
Backo Avatar asked Sep 07 '11 03:09

Backo


2 Answers

I prefer tap, as I think it provides a cleaner solution than the ones described here by not requiring any hacky deleting of elements and by clearly defining the scope in which the hash is being built.

It also means you don't need to declare an unnecessary local variable, which I always hate.

In case you haven't come across it before, tap is very simple - it's a method on Object that accepts a block and always returns the object it was called on. So to build up a hash conditionally you could do this:

Hash.new.tap do |my_hash|
  my_hash[:x] = 1 if condition_1
  my_hash[:y] = 2 if condition_2
  ...
end

There are many interesting uses for tap, this is just one.

like image 53
Russell Avatar answered Oct 01 '22 14:10

Russell


A functional approach with Hash.compact:

hash = {
  :key1 => 1,
  :key2 => (2 if condition),
  :key3 => 3,
}.compact 
like image 43
tokland Avatar answered Oct 01 '22 15:10

tokland