シリアル化するオブジェクトのキーを並べ替えてから出力します。Ruby 1.9では、ハッシュはデフォルトで順序付けられています。Ruby 1.8では、そうではありません。どちらの場合でも、active_supportのOrderedHashを使用して確認できます。
JSONデータを書き込むときはいつでも、キーを並べ替えます。Ruby 1.8では、シンボルを並べ替えることができないためto_s
、並べ替えを呼び出す必要があることに注意してください。
require 'rubygems'
require 'json'
require 'active_support/ordered_hash'
obj = {
:fig => false,
:bananas => false,
:apples => true,
:eggplant => true,
:cantaloupe => true,
:dragonfruit => false
}
def sorted_hash(hsh)
sorted_keys = hsh.keys.sort_by { |k| k.to_s }
sorted_keys.inject(ActiveSupport::OrderedHash.new) do |o_hsh, k|
o_hsh[k] = hsh[k]
o_hsh
end
end
puts JSON.pretty_generate(obj)
# Could output in any order, depending on version of Ruby
# {
# "eggplant": true,
# "cantaloupe": true,
# "dragonfruit": false,
# "fig": false,
# "bananas": false,
# "apples": true
# }
puts JSON.pretty_generate(sorted_hash(obj))
# Always output in the same order
# {
# "apples": true,
# "bananas": false,
# "cantaloupe": true,
# "dragonfruit": false,
# "eggplant": true,
# "fig": false
# }
データがオブジェクトの配列またはネストされたオブジェクトで構成されている場合は、並べ替えられたハッシュを再帰的に作成する必要があります。
nested_obj = {:a => {:d => true, :b => false}, :e => {:k => false, :f => true}, :c => {:z => false, :o => true}}
def recursive_sorted_hash(hsh)
sorted_keys = hsh.keys.sort_by { |k| k.to_s }
sorted_keys.inject(ActiveSupport::OrderedHash.new) do |o_hsh, k|
o_hsh[k] = hsh[k].is_a?(Hash) ? recursive_sorted_hash(hsh[k]) : hsh[k]
o_hsh
end
end
puts JSON.pretty_generate(nested_obj)
# Again, could be in any order
# {
# "a": {
# "b": false,
# "d": true
# },
# "e": {
# "f": true,
# "k": false
# },
# "c": {
# "z": false,
# "o": true
# }
# }
puts JSON.pretty_generate(recursive_sorted_hash(nested_obj))
# Even nested hashes are in alphabetical order
# {
# "a": {
# "b": false,
# "d": true
# },
# "c": {
# "o": true,
# "z": false
# },
# "e": {
# "f": true,
# "k": false
# }
# }