Convert hash to another hash in Ruby

I have a hash of strings

navigable_objects = { 'Dashboard' => root_path,
                      'Timesheets' => timesheets_path,
                      'Clients' => clients_path,
                      'Projects' => projects_path, 
                    }

I want to convert them to another hash, where the key is again the key, but the value is either the "active" string or the empty string, depending on whether the current controller name contains the key.

For example, let's say that the current controller name is "ClientsController". I should get the result:

{ 'Dashboard' => '',
  'Timesheets' => '',
  'Clients' => 'active',
  'Projects' => ''
}

Here's how I do it now:

active = {}

navigable_objects.each do |name, path|
  active[name] = (controller.controller_name.include?(name)) ? 'active' : '')
end 

I feel that while this works, is there a better way to do this in Ruby, perhaps using injector each_with_objects?

+5
source share
4 answers

NOTE. I already answered, but I am posting this as a separate answer because it is better for your specific situation, but my other answer still has its merits.

, each_with_object:

navigable_objects.keys.each_with_object({}) { |k,h| h[k] = controller.controller_name.include?(k) ? 'active' : '' }

:

new_hash = navigable_objects.keys.each_with_object({}) do |key, hash|
   hash[key] = controller.controller_name.include?(key) ? 'active' : ''
end

, , .

+3

: , , , . , , .

:

Hash[*navigable_objects.map{ |k,v| [k, controller.controller_name.include?(k) ? 'active' : ''] }.flatten]

map , . / . , Running Hash[*key_value_pairs.flatten] - , . , Hash[] (Hash[1, 2, 3, 4] = > { 1 => 2, 3 => 4 }). flatten , * .

, , :

key_value_pairs = navigable_objects.map do |key, value|
    new_value = controller.controller_name.include?(k) ? 'active' : ''
    [key, new_value]
end

new_hash = Hash[*key_value_pairs.flatten]

: ruby ​​1.8. :

1.9 * , Hash []

+5

. , .

inject

active = navigable_objects.inject({}) do |h, obj|
  h[obj[0]] = controller.controller_name.include?(obj[0]) ? 'active' : ''
  h
end

inject , , ( ), , , .

+1

Starting with Ruby 2.0, there is to_h:

navigable_objects.map do |name, path|
  [name, controller.controller_name.include?(name)) ? 'active' : '']
end.to_h

I don't think this is very efficient, but for small hashes this is an elegant way.

+1
source

All Articles