转化哈希结构

时间:2015-12-21 18:57:31

标签: ruby json

我有一个大的JSON对象(但是x100 +):

[
    {
        "category": "category1",
        "text": "some text"
    },
    {
        "category": "category2",
        "text": "some more text"
    },
    {
        "category": "category1",
        "text": "even more text"
    }
]

我如何将其转化为:

{
    "category1": [
        {
            "text": "some text"
        },
        {
            "text": "even more text"
        }
    ],
    "category2": {
        "text": "even more text"
    }
}

任何正确方向的帮助都将受到赞赏。

4 个答案:

答案 0 :(得分:1)

首先,您需要将JSON字符串转换为Ruby Object。

require "json"
json = %{
[
    {
        "category": "category1",
        "text": "some text"
    },
    {
        "category": "category2",
        "text": "some more text"
    },
    {
        "category": "category1",
        "text": "even more text"
    }
]
}
ary = JSON.parse(json)

现在我们有一个Ruby形式的哈希数组,我们可以操作它

h = ary.group_by {|i| i["category"]}
#=> {"category1"=>[{"category"=>"category1", "text"=>"some text"}, {"category"=>"category1", "text"=>"even more text"}], "category2"=>[{"category"=>"category2", "text"=>"some more text"}]}

h = h.map {|k,v| {k => v.map {|t| {"text" => t["text"]}}}}
#=> [{"category1"=>[{"text"=>"some text"}, {"text"=>"even more text"}]}, {"category2"=>[{"text"=>"some more text"}]}]

h = h.reduce(&:merge)
#=> {"category1"=>[{"text"=>"some text"}, {"text"=>"even more text"}], "category2"=>[{"text"=>"some more text"}]}

以漂亮的形式打印JSON以检查结果

puts JSON.pretty_generate(h)

输出:

{
  "category1": [
    {
      "text": "some text"
    },
    {
      "text": "even more text"
    }
  ],
  "category2": [
    {
      "text": "some more text"
    }
  ]
}

答案 1 :(得分:1)

def transmute(arr)
  out = Hash.new { |hash, key| hash[key] = [] }
  arr.inject(out) do |h, e|
    key = e[:category].to_sym
    entry = {text: e[:text]}        
    h[key] << entry
    h
  end
end

工作代码/规范代码段: http://rubysandbox.com/#/snippet/56784c32793916000c000000

答案 2 :(得分:1)

假设在结果中得到"category2": [{"text": "some more text"}]

array.map(&:dup).group_by{|h| h.delete(:category)}

答案 3 :(得分:0)

Enumerable#each_with_object可能有所帮助。像

这样的东西
json.each_with_object({}) do |h, acc|
  acc[h[:category]] ||= []
  acc[h[:category]] << {text: h[:text]}
end # {"category1"=>[{:text=>"some text"}, {:text=>"even more text"}], "category2"=>[{:text=>"some more text"}]}

其中json是您的原始数组。