2017-02-23 4 views
0

Ich habe folgende hash:Schlüsselpositionen in Ruby 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}} 
} 

Und ich möchte den Schlüssel parameters in jedem inneren Hash in die erste Position bewegen, etwas wie folgt aus:

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"} 
} 

ich habe den folgenden Code:

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

ich keine Fehler bekommen, aber dieser Code anyt nicht tun Hing und ich bin ziemlich verloren, wie man die Ausgabe erreicht, die ich will.

+1

Einfach nur neugierig! Warum musstest du das tun? Könnten Sie erklären :) –

+0

Ich habe mehrere YAML-Dateien, und wenn ich sie lese, ist die Ausgabe, die ich bekomme, der erste Hash, den ich hier in der Frage zeigen. Und ich verwende diese YAMLs, um ein Programm zu konfigurieren, und dieses Programm benötigt die Parameter als ersten Schlüssel des Hashs. Und ich kann die YAML-Dateien nicht ändern, also musste ich das tun :) @ PreethiKumar – mf370

Antwort

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

oder

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

Rückgabewert:

{ 
    "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

Lassen Sie uns Debug-Code:

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

Es gibt:

[["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"]] 

Es sortiert die Paare richtig, aber:

  • es gibt Arrays anstelle von Hashes
  • es das Ergebnis wieder auf den ursprünglichen Hash nicht

Für das erste Problem schreiben, Sie könnten to_h verwenden.

Für die Sekunde könnten Sie transform_values! verwenden, verfügbar in Ruby 2.4.

Hier ist der Arbeitscode, der auf Ihre vorgeschlagene Verfahren noch sehr ähnlich ist:

my_hash.transform_values! do |subhash| 
    subhash.sort_by { |k, _| k == 'parameters' ? 0 : 1 }.to_h 
end