Sorting a Hash by integer value of hash key in Ruby 1.9
Given the following hash:
{"7"=>"Ada (gnat-4.3.2)", "13"=>"Assembler (nasm-2.07)", "45"=>"Assembler (gcc-4.3.4)", "104"=>"AWK (gawk) (gawk-3.1.6)", "105"=>"AWK (mawk) (mawk-1.3.3)", "28"=>"Bash (bash 4.0.35)", "110"=>"bc (bc-1.06.95)", "12"=>"Brainf**k (bff-1.0.3.1)", "11"=>"C (gcc-4.3.4)", "27"=>"C# (mono-2.8)", "1"=>"C++ (gcc-4.3.4)", "44"=>"C++0x (gcc-4.5.1)", "34"=>"C99 strict (gcc-4.3.4)", "14"=>"CLIPS (clips 6.24)", "111"=>"Clojure (clojure 1.1.0)", "118"=>"COBOL (open-cobol-1.0)", "106"=>"COBOL 85 (tinycobol-0.65.9)", "32"=>"Common Lisp (clisp) (clisp 2.47)", "102"=>"D (dmd) (dmd-2.042)", "36"=>"Erlang (erl-5.7.3)", "124"=>"F# (fsharp-2.0.0)", "123"=>"Factor (factor-0.93)", "125"=>"Falcon (falcon-0.9.6.6)", "107"=>"Forth (gforth-0.7.0)", "5"=>"Fortran (gfortran-4.3.4)", "114"=>"Go (gc-2010-07-14)", "121"=>"Groovy (groovy-1.7)", "21"=>"Haskell (ghc-6.8.2)", "16"=>"Icon (iconc 9.4.3)", "9"=>"Intercal (c-intercal 28.0-r1)", "10"=>"Java (sun-jdk-1.6.0.17)", "35"=>"JavaScript (rhino) (rhino-1.6.5)", "112"=>"JavaScript (spidermonkey) (spidermonkey-1.7)", "26"=>"Lua (luac 5.1.4)", "30"=>"Nemerle (ncc 0.9.3)", "25"=>"Nice (nicec 0.9.6)", "122"=>"Nimrod (nimrod-0.8.8)", "43"=>"Objective-C (gcc-4.5.1)", "8"=>"Ocaml (ocamlopt 3.10.2)", "119"=>"Oz (mozart-1.4.0)", "22"=>"Pascal (fpc) (fpc 2.2.0)", "2"=>"Pascal (gpc) (gpc 20070904)", "3"=>"Perl (perl 5.12.1)", "54"=>"Perl 6 (rakudo-2010.08)", "29"=>"PHP (php 5.2.11)", "19"=>"Pike (pike 7.6.86)", "108"=>"Prolog (gnu) (g开发者_Python百科prolog-1.3.1)", "15"=>"Prolog (swi) (swipl 5.6.64)", "4"=>"Python (python 2.6.4)", "116"=>"Python 3 (python-3.1.2)", "117"=>"R (R-2.11.1)", "17"=>"Ruby (ruby-1.9.2)", "39"=>"Scala (scala-2.8.0.final)", "33"=>"Scheme (guile) (guile 1.8.5)", "23"=>"Smalltalk (gst 3.1)", "40"=>"SQL (sqlite3-3.7.3)", "38"=>"Tcl (tclsh 8.5.7)", "62"=>"Text (text 6.10)", "115"=>"Unlambda (unlambda-2.0.0)", "101"=>"Visual Basic .NET (mono-2.4.2.3)", "6"=>"Whitespace (wspace 0.3)"}
I want a hash ordered by the integer value of the hash key.
So far I've tried
languages.sort_by {|k| k[0].to_i }
and
languages.sort
where the first returns an array, and the second doesn't order by the integer value of the key(so the order is evidently wrong).
In the end I would like to have something like:
{"1" => "C++ (gcc-4.3.4)", "2" => "Pascal (gpc) (gpc 20070904)", ... }
Nice and simple (for 1.9):
hs = Hash[h.sort_by {|k,v| k.to_i }]
For example:
>> h = { '23' => 'twenty three', '11' => 'eleven', '42' => 'forty two', '1' => 'one' }
=> {"23"=>"twenty three", "11"=>"eleven", "42"=>"forty two", "1"=>"one"}
>> hs = Hash[h.sort_by {|k,v| k.to_i }]
=> {"1"=>"one", "11"=>"eleven", "23"=>"twenty three", "42"=>"forty two"}
And for more recent Rubies:
hs = h.sort_by { |k, _| k.to_i }.to_h
Here goes my solution:
languages = Hash[*languages.sort_by {|k| k[0].to_i}.flatten]
I just had to find out how to convert the array produced by
languages.sort_by {|k| k[0].to_i }
to a Hash, which I found out here.
EDIT: My solution is only Ruby 1.9 compatible. Thanks to the community I figured that out.
精彩评论