哈希在红宝石中按字母顺序排序

时间:2016-07-28 13:13:46

标签: ruby sorting hash alphabetical alphabetical-sort

我有以下哈希。

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

排序后,我希望以下列形式看到它

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

提前致谢。

3 个答案:

答案 0 :(得分:4)

简短的回答:你做不到。请参阅有关hashes in Ruby 1.8.7的文档:

  

您通过键或值遍历散列的顺序可能看起来是任意的,通常不会处于插入顺序。

在Ruby 1.8.7哈希中没有订购。甚至不能保证订单与插入密钥的顺序相匹配(就像在Ruby 1.9 +中一样)。

说:你必须使用不同的数据结构,例如数组。数组可以按其第一个值排序,并保持该顺序。

Btw:Ruby 1.8.7已经过时了很多年(它的继任者Ruby 1.9 was released six years ago)。 Ruby 1.8.7缺少一些有趣的功能,不再获得安全更新,许多宝石都不再支持这个旧版本。我建议至少更新到Ruby 2.2 +

答案 1 :(得分:0)

用RubyDocs编写:

  

哈希按照相应键的顺序枚举其值   插入了。

所以你需要为你的目的创建新的哈希:

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

答案 2 :(得分:0)

对于Ruby v.1.9.3 +,

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

请参阅Array#<=>文档的第三段,了解Ruby如何命令数组,这决定了它们的排序顺序。

我的结果与您的次要排序不同。您的主要分类是

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

这很好,但是对于以"a""A"开头的字符串的次要排序,您希望

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

既不是

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

,也不

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

所以这就引出了一个问题,“你的二级排序标准是什么?”

相关问题