通过哈希迭代。但是,我的价值每次都在改变

时间:2017-11-24 09:13:01

标签: ruby-on-rails json

我目前正在处理一个简单的哈希循环,以操纵一些json数据。这是我的Json数据:

{
 "polls": [
   { "id": 1, "question": "Pensez-vous utiliser le service de cordonnerie/pressing au moins 2 fois par mois ?" },
   { "id": 2, "question": "Avez-vous passé une bonne semaine ?" },
   { "id": 3, "question": "Le saviez-vous ? Il existe une journée d'accompagnement familial." }
 ],
 "answers": [
   { "id": 1, "poll_id": 1, "value": true },
   { "id": 2, "poll_id": 3, "value": false },
   { "id": 3, "poll_id": 2, "value": 3 }
 ]
}

我希望获得poll_id值和来自answers hash的值。所以这就是我的代码:

require 'json'

file = File.read('data.json')
datas = JSON.parse(file)

result = Hash.new

datas["answers"].each do |answer|
  result["polls"] = {"id" => answer["poll_id"], "value" => answer["value"]}
end
polls_json = result.to_json

然而,它让我回复:

{
  "polls": {
    "id": 2,
    "value": 3
  }
}

这是我正在寻找的输出:

{
  "polls": [
    {
      "id": 1,
      "value": true
    },
   {
      "id": 2,
      "value": 3
    },
   {
      "id": 3,
      "value": false
   }
 ]
}

似乎该值未保存到我的循环中。我尝试了不同的方法,但我仍然找不到解决方案..有什么建议吗?

3 个答案:

答案 0 :(得分:1)

你应该在这里使用reduce,即

datas["answers"].reduce({ polls: [] }) do |hash, data|
  hash[:polls] << { id: data["poll_id"], value: data["value"] }
  hash
end

此方法遍历答案,使提供给reduce的对象(在本例中为具有:polls数组的哈希)可用于传递每个数据哈希。

我个人,嗯,通过以下方式进一步减少这一点,尽管可读性需要付出一些代价:

datas["answers"].reduce({ polls: [] }) do |hash, data|
  hash.tap { |h| h[:polls] << { id: data["poll_id"], value: data["value"] } }
end

使用内置的方法,这是实现您所需要的最干净的方法。

reduce的文档:https://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-reduce

(我也倾向于更新变量名称 - 数据已经是复数,所以'数据'对其他任何人来说都有点混乱。)

编辑:@max从您的数据中获得一个很好的重要符号/字符串键 - 如果您尝试应用它,请记住这一点。

答案 1 :(得分:0)

尝试以下方法:

require 'json'

file = File.read('data.json')
datas = JSON.parse(file)

result = Hash.new
poll_json = []

datas["answers"].each do |answer|
  poll_json << {"id" => answer["poll_id"], "value" => answer["value"]}
end
p "json = "#{poll_json}"

答案 2 :(得分:0)

{
  polls: datas["answers"].map do |a|
    { id: a["poll_id"], value: a["value"] }
  end
}

通常使用.map来遍历数组和散列并返回新对象。 .each只应在您只关注副作用时使用(例如在输出值时的视图中)。

require 'json'

json = JSON.parse(File.read('data.json'))

result = {
  polls: json["answers"].map do |a|
    { id: a["poll_id"], value: a["value"] }
  end
}

puts result.to_json

输出结果为:

{"polls":[{"id":1,"value":true},{"id":3,"value":false},{"id":2,"value":3}]}