Search code examples
rubyhashblock

What is an elegant Ruby way to have a condition of 'nil'?


Is there a more elegant way to write this code?

    def create_a_hash_from_a_collection
      my_hash = {}

      collection_of_hashes.each do |key, value|
        my_hash[key] = {} if my_hash[key].nil?
        my_hash[key] = value
      end

      my_hash
    end

The line that seems clumsy to me is this:

my_hash[key] = {} if my_hash[key].nil?

Is there a shorthand way of expressing it?


Solution

  • You can use ||= operator which does exactly what you want

    my_hash[key] ||= {} 
    

    The rest of my answer here is because I'm not sure what a "collection of hashes" is, so my best guess is that it would be an array of hashes. If I'm wrong, let me know and disregard the rest of this answer.

    It seems that the rest of your method may not do what it sounds like you're trying to do. Consider:

    @collection_of_hashes = [{foo: 'bar'}, {baz: 'qux'}]
    
    def create_a_hash_from_a_collection
       my_hash = {}
       @collection_of_hashes.each do |key, value|
         # this is not actually doing anything here and returns same with or
         # without the following line
         # my_hash[key] ||= {}
         my_hash[key] = value
       end
    
       my_hash
     end
    #=> {{:foo=>"bar"}=>nil, {:baz=>"qux"}=>nil}
    

    But what you probably want is

    def create_a_hash_from_a_collection
      my_hash = {}
      @collection_of_hashes.each do |hash|
        hash.keys.each do |k|
          my_hash[k] = hash[k]
        end
      end
      my_hash
    end
    #=> {:foo=>"bar", :baz=>"qux"}
    

    But also keep in mind, if any of your "collection of hashes" which we would tend to assume would be an array of hashes, contain the same key, which one wins? This code, it would be the last item in the array's key value. What is the actual goal of your method?