如何在红宝石模板中输出排序后的哈希

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

我目前正在使用

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

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

我也试过了

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

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

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

"beanstalkd": "server1",

代替

"beanstalkd": ["server1"],

我一直在为此打了几天,所以想要一些帮助


哈希是一个无序的数据结构。 在某些语言中(例如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}

由于Ruby中的哈希是有序的,并且问题用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,则不会出现这种情况,因为所有的键都是字符串。)

链接地址: http://www.djcxy.com/p/10543.html

上一篇: How to output sorted hash in ruby template

下一篇: The Persistent Domain Objects pattern