8

我正在为我们的一个内联应用程序构建一个配置文件。它本质上是一个 json 文件。我在让 puppet/ruby 1.8 每次都以相同的方式输出 hash/json 时遇到了很多麻烦。

我目前正在使用

<%= require "json"; JSON.pretty_generate data %>

但是在输出人类可读的内容时,它并不能保证每次都具有相同的顺序。这意味着 puppet 会经常针对相同的数据发送更改通知。

我也试过

<%= require "json"; JSON.pretty_generate Hash[*data.sort.flatten] %>

每次都会生成相同的数据/订单。当数据具有嵌套数组时,问题就出现了。

data => { beanstalkd => [ "server1", ] }

变成

"beanstalkd": "server1",

代替

"beanstalkd": ["server1"],

我已经断断续续地为此奋斗了几天,所以需要一些帮助

4

2 回答 2

3

由于 Ruby 中的哈希有序的,并且问题被标记为​​ ,这里有一个方法可以递归地对哈希进行排序(不影响数组的排序):

def sort_hash(h)
  {}.tap do |h2|
    h.sort.each do |k,v|
      h2[k] = v.is_a?(Hash) ? sort_hash(v) : v
    end
  end
end

h = {a:9, d:[3,1,2], c:{b:17, a:42}, b:2 }
p sort_hash(h)
#=> {:a=>9, :b=>2, :c=>{:a=>42, :b=>17}, :d=>[3, 1, 2]}

require 'json'
puts sort_hash(h).to_json
#=> {"a":9,"b":2,"c":{"a":42,"b":17},"d":[3,1,2]}

请注意,如果您的哈希具有无法比较的键,这将灾难性地失败。(如果您的数据来自 JSON,则情况并非如此,因为所有键都是字符串。)

于 2015-04-13T18:02:15.030 回答
0

哈希是一种无序的数据结构。在某些语言(例如 ruby​​)中,有一个有序版本的哈希,但在大多数情况下,在大多数语言中,您不应该依赖哈希中的任何特定顺序。

如果顺序对您很重要,您应该使用数组。所以,你的哈希

{a: 1, b: 2}

变成这个

[{a: 1}, {b: 2}]

我认为,它不会强制对您的代码进行太多更改。

针对您的情况的解决方法

试试这个:

data = {beanstalkId: ['server1'], ccc: 2, aaa: 3}

data2 = data.keys.sort.map {|k| [k, data[k]]}

puts Hash[data2]
#=> {:aaa=>3, :beanstalkId=>["server1"], :ccc=>2}
于 2012-03-16T08:06:21.143 回答