2016-07-28 11 views
0

Ich habe den folgenden Hash.Hash Sortierung alphabetisch in Rubin

h = { 
    "31d2fcd5-aec0-438d-895c-806fd0358c23"=>{"name"=>"q", 'database'=>'mysql'}, 
    "69a05dea-d767-44b7-b40c-f76d0d12f8c1"=>{"name"=>"Qwerty", 'database'=>'H2'}, 
    "69a05dea-d767-44b7-b40c-f76d0d121993"=>{"name"=>"b", 'database'=>'postgresql'}, 
    "69a05dea-d767-44b7-b40c-f76d0d121994"=>{"name"=>"B", 'database'=>'oracle'}, 
    "69a05dea-d767-44b7-b40c-f76d0d121995"=>{"name"=>"Apple", 'database'=>'sqlite3'}, 
    "69a05dea-d767-44b7-b40c-f76d0d521996"=>{"name"=>"a", 'database'=>'mariadb'}, 
    "69a05dea-d767-44b7-b40c-f76d0d1k1996"=>{"name"=>"A", 'database'=>'mongodb'} 
} 

Nach der Sortierung ich es

in der folgenden Form sehen möchte vorab
h = { 
    "31d2fcd5-aec0-438d-895c-806fd0358c23"=>{"name"=>"a", 'database'=>'mariadb'}, 
    "69a05dea-d767-44b7-b40c-f76d0d12f8c1"=>{"name"=>"A", 'database'=>'mongodb'}, 
    "69a05dea-d767-44b7-b40c-f76d0d121993"=>{"name"=>"Apple", 'database'=>'sqlite3'}, 
    "69a05dea-d767-44b7-b40c-f76d0d121994"=>{"name"=>"b", 'database'=>'postgresql'}, 
    "69a05dea-d767-44b7-b40c-f76d0d121995"=>{"name"=>"B", 'database'=>'oracle'}, 
    "69a05dea-d767-44b7-b40c-f76d0d521996"=>{"name"=>"q", 'database'=>'mysql'}, 
    "69a05dea-d767-44b7-b40c-f76d0d1k1996"=>{"name"=>"Qwerty", 'database'=>'H2'} 
} 

Danke.

+1

Wenn Sie die Anforderung einer bestimmten Bestellung haben dann eine [Hash-Tabelle] (https: //en.wikipedia.org/wiki/Hash_table) ist möglicherweise nicht die richtige Datenstruktur für Sie, da Hashtabellen eine ungeordnete Datenstruktur darstellen. Selbst wenn Rubys Hash seit Version 1.9.3 stabil sortiert ist, sollten Sie sich nicht darauf verlassen, da Sie jedes Mal, wenn Sie ein Element hinzufügen, manuell neu ordnen müssen. – spickermann

+0

Meine Ruby-Version ist 1.8.7 –

+0

Sie möchten vielleicht erläutern, warum Sie diesen Hash sortieren möchten. Dann können wir möglicherweise einen Workaround vorschlagen. – spickermann

Antwort

0

Wie es in RubyDocs geschrieben wird:

Hashes aufzuzählen deren Werte in der Reihenfolge, in der entsprechenden Tasten eingefügt wurden.

Sie müssen also neue Hash für Ihre Zwecke erstellen:

h.to_a.sort_by{|s| s[1]['name']}.to_h 

{ 
    "69a05dea-d767-44b7-b40c-f76d0d1k1996"=>{"name"=>"A", "database"=>"mongodb"}, 
    "69a05dea-d767-44b7-b40c-f76d0d121995"=>{"name"=>"Apple", "database"=>"sqlite3"}, 
    "69a05dea-d767-44b7-b40c-f76d0d121994"=>{"name"=>"B", "database"=>"oracle"}, 
    "69a05dea-d767-44b7-b40c-f76d0d12f8c1"=>{"name"=>"Qwerty", "database"=>"H2"}, 
    "69a05dea-d767-44b7-b40c-f76d0d521996"=>{"name"=>"a", "database"=>"mariadb"}, 
"69a05dea-d767-44b7-b40c-f76d0d121993"=>{"name"=>"b", "database"=>"postgresql"}, 
"31d2fcd5-aec0-438d-895c-806fd0358c23"=>{"name"=>"q", "database"=>"mysql"} 
} 
+0

Ich glaube nicht, dass das die Bestellung produziert, die das OP angefordert hat. – Seth

+0

Mikhail Chuprynski Ihr geschriebener Code arbeitet an den Ruby-Online-Redaktoren, funktioniert aber nicht für meinen PC. Übrigens ist meine Rubinversion 1.8.7. –

+1

@KhachaturSaribekyan können Sie 'Hash [h.to_a.sort_by {| s | s [1] ['name']}] ' –

4

Kurze Antwort: Sie können nicht. Lesen Sie die Dokumentation über hashes in Ruby 1.8.7:

Die Reihenfolge, in der Sie einen Hash durchqueren entweder durch Schlüssel oder Wert kann willkürlich erscheinen, und wird in der Regel nicht im Anzeigenauftrag sein.

In Ruby 1.8.7 Hashes sind nicht geordnet. Es ist nicht einmal garantiert, dass die Reihenfolge der Reihenfolge entspricht, in der die Schlüssel eingefügt wurden (wie in Ruby 1.9+).

Das sagte: Sie müssen eine andere Datenstruktur verwenden, wie ein Array zum Beispiel. Arrays können nach ihrem ersten Wert sortiert werden, und sie würden diese Reihenfolge beibehalten.

Btw: Ruby 1.8.7 ist schon viele Jahre veraltet (sein Nachfolger Ruby 1.9 was released six years ago). Ruby 1.8.7 hat einige interessante Features verloren, erhält keine Sicherheitsupdates mehr und viele Edelsteine ​​haben die Unterstützung für diese alte Version fallen gelassen. Ich rate zu mindestens Rubin 2.2+

0

für Ruby v.1.9.3 + zu aktualisieren,

h.sort_by { |_,v| [v["name"][0].downcase, v["name"]] }.to_h 
    #=> {"69a05dea-d767-44b7-b40c-f76d0d1k1996"=>{"name"=>"A", "database"=>"mongodb"}, 
    # "69a05dea-d767-44b7-b40c-f76d0d121995"=>{"name"=>"Apple", "database"=>"sqlite3"}, 
    # "69a05dea-d767-44b7-b40c-f76d0d521996"=>{"name"=>"a", "database"=>"mariadb"}, 
    # "69a05dea-d767-44b7-b40c-f76d0d121994"=>{"name"=>"B", "database"=>"oracle"}, 
    # "69a05dea-d767-44b7-b40c-f76d0d121993"=>{"name"=>"b", "database"=>"postgresql"}, 
    # "69a05dea-d767-44b7-b40c-f76d0d12f8c1"=>{"name"=>"Qwerty", "database"=>"H2"}, 
    # "31d2fcd5-aec0-438d-895c-806fd0358c23"=>{"name"=>"q", "database"=>"mysql"}} 

den dritten Absatz des Dokuments Siehe Array#<=> für eine Erklärung, wie Arrays Ruby-Aufträge, die bestimmt, ihre sortierte Reihenfolge.

Mein Ergebnis unterscheidet sich von Ihrem in der sekundären Sortierung. Ihre primäre Art ist

["q", "Qwerty", "b", "B", "Apple", "a", "A"].sort_by { |s| s[0].downcase } 
    #=> ["a", "Apple", "A", "B", "b", "q", "Qwerty"] 

was in Ordnung ist, aber Ihre sekundäre Sortier auf Strings mit "a" oder "A" beginnen, die Sie sein wollen

["a", "A", "Apple"] 

ist weder

["a", "Apple", "A"].sort 
    # => ["A", "Apple", "a"] 

noch

["a", "Apple", "A"].sort.reverse 
    #=> ["a", "Apple", "A"] 

so stellt sich die Frage "Was ist Ihr sekundäres Sortierkriterium"?

Verwandte Themen