Ordered Hash by keys


Recently, I have to implement my own Hash sorting method. Not really with Hash but with ActiveSupport::OrderedHash

      I don’t like the way ActiveSupport::OrderedHash behaves with sorting functionality.
      It just behaves like a simple Hash
      I would like that sort return an ActiveSupport::OrderedHash not an Arrray!!! Why is it called OrderedHash in this case ?
      I would like to sort with keys only, not with an array [key, value]

Ok no matter, I implemented my own new SimpleOrderedHash :

require 'active_support/ordered_hash'
class SimpleOrderedHash < ActiveSupport::OrderedHash
 
  # Lets reimplement sort method
  def sort(&block)
    h = self.dup
    h.sort!(&block)
    h
  end
 
  # Lets implement sort! method
  # It uses @keys variable to do the sorting
  def sort!(&block)
    @keys.sort!(&block)
    sync_keys!
    self
  end
 
  # A fancy inspect   
  def inspect
    "#<#{self.class.name} #{Hash.instance_method(:inspect).bind(self).call}>"
  end
end

You can now use it like that :

h = SimpleOrderedHash.new
h.merge!({'second' => 1, 'first' => 5, 'third' => 2.5})
=> #<SimpleOrderedHash {"third"=>2.5, "second"=>1, "first"=>5}>
 
# sort return a SimpleOrderedHash
result = h.sort do |a,b|
  h[a] <=> h[b]
end
=> #<SimpleOrderedHash {"third"=>2.5, "second"=>1, "first"=>5}>
 
# and order as I wanted
result.each{ |k,v| puts v }
1
2.5
5
=> ["second", "third", "first"]
 
# sort! change internally the order of a SimpleOrderedHash
h.sort! do |a,b|
  h[b] <=> h[a]
end
h.each{ |k,v| puts v }
5
2.5
1
=> ["first", "third", "second"]

, , , , , , , ,

  1. No comments yet.
(will not be published)