Convert Hash to Ordered Hash with Rails 2.3+ and Ruby 1.8

written by seb on January 15th, 2010 @ 10:39 AM

Problem

Ruby 1.8 doesn't support Ordered Hash.

You do not need this if using Ruby 1.9

Solution

Rails brought this with ActiveSupport::OrderedHash to make it behave much like Ruby 1.9 Hash in the ordering way.

Remaining problem

When you've got a Hash, containing Hash, Array, ... them selves containing more Hash, Array, ... you need a simple way to convert all this hash to ActiveRecord::OrderedHash (if running Ruby 1.8).

Solution to convert all Hash as ActiveSupport::OrderedHash only if Ruby is under 1.9

def convert_hash_to_ordered_hash(object, deep = false)
  # Hash is ordered in Ruby 1.9!
  if RUBY_VERSION >= '1.9'
    return object
  else
    if object.is_a?(Hash)
      returning(ActiveSupport::OrderedHash.new) do |map|
        object.each {|k,v| map[k] = deep ? convert_hash_to_ordered_hash(v, deep) : v }
      end
    elsif deep && object.is_a?(Array)
      array = Array.new
      object.each_with_index {|v,i| array[i] = convert_hash_to_ordered_hash(v, deep) }
      return array
    else
      return object
    end
  end
end

How to use :

>> b = {"a"=>{"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}, "b"=>{"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}, "c"=>{"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>{"a"=>"bc", "b"=>"b", "c"=>"c"}}, "d"=>["a", "c", "b", {"a"=>"a", "b"=>"b", "c"=>"c"}]}
=> {"a"=>{"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}, "b"=>{"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}, "c"=>{"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>{"a"=>"bc", "b"=>"b", "c"=>"c"}}, "d"=>["a", "c", "b", {"a"=>"a", "b"=>"b", "c"=>"c"}]}
>> convert_hash_to_ordered_hash(b, false)
=> #<OrderedHash {"a"=>{"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}, "b"=>{"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}, "c"=>{"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>{"a"=>"bc", "b"=>"b", "c"=>"c"}}, "d"=>["a", "c", "b", {"a"=>"a", "b"=>"b", "c"=>"c"}]}>
>> convert_hash_to_ordered_hash([b], false)
=> [{"a"=>{"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}, "b"=>{"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}, "c"=>{"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>{"a"=>"bc", "b"=>"b", "c"=>"c"}}, "d"=>["a", "c", "b", {"a"=>"a", "b"=>"b", "c"=>"c"}]}]
>> convert_hash_to_ordered_hash(b, true)
=> #<OrderedHash {"a"=>#<OrderedHash {"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}>, "b"=>#<OrderedHash {"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}>, "c"=>#<OrderedHash {"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>#<OrderedHash {"a"=>"bc", "b"=>"b", "c"=>"c"}>}>, "d"=>["a", "c", "b", #<OrderedHash {"a"=>"a", "b"=>"b", "c"=>"c"}>]}>
>> convert_hash_to_ordered_hash([b], true)
=> [#<OrderedHash {"a"=>#<OrderedHash {"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}>, "b"=>#<OrderedHash {"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}>, "c"=>#<OrderedHash {"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>#<OrderedHash {"a"=>"bc", "b"=>"b", "c"=>"c"}>}>, "d"=>["a", "c", "b", #<OrderedHash {"a"=>"a", "b"=>"b", "c"=>"c"}>]}>]
>> b
=> {"a"=>{"aa"=>"ca", "a"=>"ba", "ba"=>"aa"}, "b"=>{"bb"=>"ab", "ab"=>"cb", "b"=>"bb"}, "c"=>{"aa"=>["a", "c", "b"], "bc"=>"ac", "ac"=>"cc", "c"=>{"a"=>"bc", "b"=>"b", "c"=>"c"}}, "d"=>["a", "c", "b", {"a"=>"a", "b"=>"b", "c"=>"c"}]}

Comments are closed