It figures that one of the questions someone asked, following my talk on sorting last month, was something I specifically chose not to cover for the sake of time, and to be able to cover more valuable topics. So, when someone asked whether you can sort a Hash and how, I knew A) that you can, and B) I knew I had barely glanced at it in the rdoc on hash sorting, but didn’t remember how it worked. So I had to simply suggest they go read about it themselves. But I was also curious to go read about it more myself. So I took my own advice, and here’s what I came up with:
I define a hash:
irb(main):001:0> typical_fish_colors =
irb(main):002:0* {"clownfish" => ["orange","white","black"],
irb(main):003:1* "goldfish" => ["orange"],
irb(main):004:1* "angelfish" => ["black","white"]
irb(main):005:1> }
Default sorting on a hash – sorts the keys.
Pretty simple I guess. What you may not expect, depending on what you know of hashes, is that you don’t get a Hash object returned from calling .sort, you get an Array. A nested, three-dimensional Array. This is because arrays are ordered, hashes are not.
irb(main):006:0> typical_fish_colors.sort => [["angelfish", ["black", "white"]], ["clownfish", ["orange", "white", "black"]], ["goldfish", ["orange"]]]
What you can’t do when sorting a hash is use sort! (sort-bang):
irb(main):007:0> typical_fish_colors.sort! NoMethodError: undefined method `sort!' for #<Hash:0x2d17ea8> from (irb):7
What else you can’t do when sorting a hash by default is use symbols for keys:
irb(main):008:0> typical_fish_colors =
irb(main):009:0* {:clownfish => ["orange","white","black"],
irb(main):010:1* :goldfish => ["orange"],
irb(main):011:1* :angelfish => ["black","white"]
irb(main):012:1> }
irb(main):013:0> typical_fish_colors.sort
NoMethodError: undefined method `<=>' for :clownfish:Symbol
from (irb):13:in `<=>'
from (irb):13:in `sort'
from (irb):13