Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional key/value in a ruby hash

Tags:

ruby

Is there a nice (one line) way of writing a hash in ruby with some entry only there if a condition is fulfilled? I thought of

{:a => 'a', :b => ('b' if condition)} 

But that leaves :b == nil if the condition is not fulfilled. I realize this could be done easily in two lines or so, but it would be much nicer in one line (e.g. when passing the hash to a function).

Am I missing (yet) another one of ruby's amazing features here? ;)

like image 729
lucas clemente Avatar asked Apr 21 '11 23:04

lucas clemente


People also ask

How do you check if a key-value exists in a Hash Ruby?

Overview. We can check if a particular hash contains a particular key by using the method has_key?(key) . It returns true or false depending on whether the key exists in the hash or not.

How do I get the key-value in Ruby?

You can find a key that leads to a certain value with Hash#key . If you are using a Ruby earlier than 1.9, you can use Hash#index . Once you have a key (the keys) that lead to the value, you can compare them and act on them with if/unless/case expressions, custom methods that take blocks, et cetera.

How do you add a value to a Hash in Ruby?

Hash literals use the curly braces instead of square brackets and the key value pairs are joined by =>. For example, a hash with a single key/value pair of Bob/84 would look like this: { "Bob" => 84 }. Additional key/value pairs can be added to the hash literal by separating them with commas.

Does key exist in Hash Ruby?

Sets the default value, the value returned for a key that does not exist in the hash. It is not possible to set the default to a Proc that will be executed on each key lookup.


1 Answers

UPDATE Ruby 2.4+

Since ruby 2.4.0, you can use the compact method:

{ a: 'a', b: ('b' if cond) }.compact 

Original answer (Ruby 1.9.2)

You could first create the hash with key => nil for when the condition is not met, and then delete those pairs where the value is nil. For example:

{ :a => 'a', :b => ('b' if cond) }.delete_if{ |k,v| v.nil? } 

yields, for cond == true:

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

and for cond == false

{:a=>"a"}  

UPDATE for ruby 1.9.3

This is equivalent - a bit more concise and in ruby 1.9.3 notation:

{ a: 'a', b: ('b' if cond) }.reject{ |k,v| v.nil? } 
like image 164
Thilo Avatar answered Sep 22 '22 18:09

Thilo