2017-02-23 54 views
0

У меня есть следующий хэш:Изменить ключевые позиции в Руби Hash

my_hash = { 
    "redis_1"=>{"group"=>"Output", "name"=>"Redis", "parameters"=>{"redis_db"=>2, "redis_password"=>"<password>"}}, 
    "file_1"=>{"name"=>"File", "group"=>"Output", "parameters"=>{"file"=>"/opt/var/lib/bots/file-output/ctt.txt", "hierarchical_output"=>false}} 
} 

И я хотел бы, чтобы переместить ключ parameters в каждой внутренней хэш на первую позицию, что-то вроде этого:

my_hash = { 
    "redis_1"=>{"parameters"=>{"redis_db"=>2, "redis_password"=>"<password>"}, "group"=>"Output", "name"=>"Redis"}, 
    "file_1"=>{"parameters"=>{"file"=>"/opt/var/lib/bots/file-output/ctt.txt", "hierarchical_output"=>false}, "name"=>"File", "group"=>"Output"} 
} 

у меня есть следующий код:

my_hash.each_pair do |key, value| 
    value.sort_by {|k, v| k == "parameters" ? 0 : 1} 
end 

Я не получаю какие-либо ошибки, но этот код не делает anyt hing, и я совершенно потерял, как достичь результата, который я хочу.

+1

Просто любопытен! Зачем вам это нужно? Не могли бы вы объяснить :) –

+0

У меня есть несколько файлов YAML, и когда я их читаю, вывод, который я получаю, является первым хэшем, который я показываю здесь в вопросе. И я использую эти YAML для настройки программы, и эта программа нуждается в параметрах в качестве первого ключа хэша. И я не могу изменить файлы YAML, поэтому мне нужно было это сделать :) @PreethiKumar – mf370

ответ

1
my_hash 
.each {|k, v| my_hash[k] = {"parameters" => v.delete("parameters")}.merge(v)} 

или

my_hash 
.each_value{|v| v.replace({"parameters" => v.delete("parameters")}.merge(v))} 

Возвращаемое значение:

{ 
    "redis_1"=>{"parameters"=>{"redis_db"=>2, "redis_password"=>"<password>"}, "group"=>"Output", "name"=>"Redis"}, 
    "file_1"=>{"parameters"=>{"file"=>"/opt/var/lib/bots/file-output/ctt.txt", "hierarchical_output"=>false}, "name"=>"File", "group"=>"Output"} 
} 
1

Давайте отлаживать код:

my_hash.each_pair do |key, value| 
    p value.sort_by {|k, v| k == "parameters" ? 0 : 1} 
end 

Он выдает:

[["parameters", {"redis_db"=>2, "redis_password"=>"<password>"}], ["group", "Output"], ["name", "Redis"]] 
[["parameters", {"file"=>"/opt/var/lib/bots/file-output/ctt.txt", "hierarchical_output"=>false}], ["name", "File"], ["group", "Output"]] 

Он сортирует пары правильно, но:

  • возвращает массив вместо хэшей
  • он не записывает результат обратно в исходный хэш

Для первой задачи, вы можете использовать to_h.

Для второго можно использовать transform_values!, доступный в Ruby 2.4.

Вот рабочий код, который по-прежнему очень похож на ваш предложенный метод:

my_hash.transform_values! do |subhash| 
    subhash.sort_by { |k, _| k == 'parameters' ? 0 : 1 }.to_h 
end 
Смежные вопросы