Posortuj klucze obiektów serializowanych przed ich wyprowadzeniem. W Ruby 1.9 hasze są domyślnie sortowane; w Rubim 1.8 nie są. Możesz użyć OrderedHash z active_support, aby mieć pewność w obu przypadkach.
Ilekroć masz zamiar pisać dane JSON, posortuj klucze. Zauważ, że w Ruby 1.8 symbole nie mogą być posortowane, więc musisz zadzwonić pod numer 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
# }
Jeśli dane składa się z szeregu obiektów lub obiektów zagnieżdżonych, musisz utworzyć posortowane mieszań rekurencyjnie:
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
# }
# }
Dzięki. To będzie ładnie działać. –
Uwaga: działa to, ponieważ 'sort_keys = True' w implementacji' json.tool', ale ta gwarancja nie jest nigdzie udokumentowana, więc warto napisać własny skrypt, który może zapewnić tę gwarancję: 'import json, sys; print json.dumps (json.load (sys.stdin), sort_keys = True) ' –