views:

444

answers:

5

I'm building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished?

hash.to_xml
A: 

What order did you want them to be in? You shouldn't expect them to be in insertion order. From the docs for Hash:

The order in which you traverse a hash by either key or value may seem arbitrary, and will generally not be in the insertion order.

If you need them to be in a specific order you can determine just from the keys/values (e.g. order the attribute names alphabetically), you'll need to apply that ordering explicitly.

Jon Skeet
+1  A: 

The usual ways of sorting a hash is by key or value. Have a look here:

hash.sort

More complex sorts can be accomplised however by utilizing the spaceship operator

ennuikiller
+1  A: 
h = Hash[:x,123,:a,553,:d,949,:e,5321]
=> {:e=>5321, :x=>123, :a=>553, :d=>949}
h.sort { |x,y| x[0].to_s <=> y[0].to_s }
=> [[:a, 553], [:d, 949], [:e, 5321], [:x, 123]]
DigitalRoss
+4  A: 

Ruby 1.8's hash aren't in insertion order. With ruby 1.9, they will be.

However rails offers an alternative to that, the class OrderedHash.

my_hash = ActiveSupport::OrderedHash.new
my_hash[:key] = 'value'
my_hash[:second_key] = 'second value'

This hash is in fact an array of that format :

[[:key, 'value'], [:second_key, 'second value']]

The entries remains in the order you inserted them.
And you can access them like with any other hash.

Damien MATHIEU
Tried this with no luck. It still displays randomly. Using Ruby 1.8.7.
Jeffrey
A: 

This piece of code I've just made for i18n-js might help you out as it convert Hash to ActiveSupport::OrderedHash if needed then sort it's key by natural order.

http://seb.box.re/2010/1/15/deep-hash-ordering-with-ruby-1-8

Sébastien Grosjean - ZenCocoon