Hi everyone! is it impossible to sort a hash by key? I have a hash like {"plums"=>3, "bananas"=>4, "apples"=>6} And what i want is {"apples" => 6, "bananas" => 4, "plums" => 3} Hash#sort returns an array. So i've tried this: class Hash def sort_by_key array = self.sort # the array is sorted! array.inject({}) do |hash, value| hash[value.first] = value.last hash end end end But the result is {"plums"=>3, "bananas"=>4, "apples"=>6}! So - is it impossible to sort a hash by key? Oliver.

on 2006-06-14 09:03

on 2006-06-14 09:12

```
Oliver Katzer wrote:
> is it impossible to sort a hash by key?
Yes, because hashes are un-ordered containers.
Look up OrderedHash on the RAA for one possible solution.
Cheers,
Dave
```

on 2006-06-14 09:15

Hashes are by definition nonsortable. There is no guarantee that the order you put them in will be the order you access them. The order they appear in the hash probably has something to do with the hashed value of each key (I think).

on 2006-06-14 09:22

On Jun 14, 2006, at 3:03 AM, Oliver Katzer wrote: > class Hash > But the result is {"plums"=>3, "bananas"=>4, "apples"=>6}! > > So - is it impossible to sort a hash by key? > > Oliver. > > -- > Posted via http://www.ruby-forum.com/. > A hash's order is not guaranteed. If you want to display the hash in sorted order you can do something like the following % cat sorted_hash.rb class Hash def each_ordered_by_key keys.sort.each do |key| yield(key, self[key]) end end end str = "{" hash = {"plums"=>3, "bananas"=>4, "apples"=>6} hash.each_ordered_by_key do |key, value| str << "#{key.inspect}=>#{value.inspect}, " end str[-2, 2] = "}" puts str % ruby sorted_hash.rb {"apples"=>6, "bananas"=>4, "plums"=>3}

on 2006-06-14 09:32

Dave, Farrel, Logan - Thanks for your quick replys! Hash#each_ordered_by_key is a good solution for my problem. Oliver.

on 2006-06-14 09:39

On 6/14/06, Oliver Katzer <ok@yum.de> wrote: > class Hash > But the result is {"plums"=>3, "bananas"=>4, "apples"=>6}! > > So - is it impossible to sort a hash by key? > > Oliver. > > -- > Posted via http://www.ruby-forum.com/. > > Hashes are unordered, an "ordered hash" is an oxymoron. If you need a hash to be ordered, the easiest way is to use an array. irb(main):001:0> hsh = {:a => 1, :b => 2, :c => 3, :d => 4} => {:d=>4, :b=>2, :c=>3, :a=>1} irb(main):002:0> hsh.sort_by { |k,v| k } NoMethodError: undefined method `<=>' for :d:Symbol from (irb):2:in `sort_by' from (irb):2 from :0 irb(main):003:0> hsh.sort_by { |k,v| k.to_s } => [[:a, 1], [:b, 2], [:c, 3], [:d, 4]]

on 2006-06-14 11:51

On 14/06/06, Matthew Harris <shugotenshi@gmail.com> wrote: > Hashes are unordered, an "ordered hash" is an oxymoron. > If you need a hash to be ordered, the easiest way is to use an array. ... > => [[:a, 1], [:b, 2], [:c, 3], [:d, 4]] And you can then use assoc to look up the corresponding element: a = [[:a, 1], [:b, 2], [:c, 3], [:d, 4]] a.assoc(:c)[1] #=> 3 The look-up performance for large arrays will be far inferior to that of a hash, however. Paul.

on 2006-06-14 12:00

> h={:c=> 1, :b=> 2, :a => 3} > a=[] > h.keys.sort_by {|s| s.to_s}.each {|key| puts h[key] } > puts a => [[:a, 3], [:b, 2], [:c, 1]] -------- Original-Nachricht -------- Datum: Wed, 14 Jun 2006 18:48:06 +0900 Von: Paul Battley <pbattley@gmail.com> An: ruby-talk@ruby-lang.org Betreff: Re: impossible to sort a hash by key?

on 2006-06-14 12:03

shorter: > h={:c=> 1, :b=> 2, :a => 3} > h.keys.sort_by {|s| s.to_s}.map {|key| [key, h[key]] } -------- Original-Nachricht -------- Datum: Wed, 14 Jun 2006 18:48:06 +0900 Von: Paul Battley <pbattley@gmail.com> An: ruby-talk@ruby-lang.org Betreff: Re: impossible to sort a hash by key?

on 2006-06-15 06:41

> From: Peter Ertl [mailto:pertl@gmx.org] > > shorter: > > > h={:c=> 1, :b=> 2, :a => 3} > > h.keys.sort_by {|s| s.to_s}.map {|key| [key, h[key]] } Shorter, faster, and (to my mind) clearer: h.to_a.sort_by {|k,v| k.to_s } If you're not using symbols for your keys, you can just do: h.to_a.sort (I'm guessing that using OrderedHash will have the same problem of symbols not being comparable in this situation).

on 2006-06-15 07:13

```
Daniel Sheppard wrote:
> h.to_a.sort_by {|k,v| k.to_s }
Or even:
h.sort_by {|k,v| k.to_s }
```

on 2011-01-15 15:48

Although an old topic, this example could be useful to someone: h = ENV.to_hash h.keys.sort.each{|k| puts k + " => " + h[k] + "<br>\n"}