循环哈希并在rails上的ruby中生成新的哈希/数组

时间:2017-10-15 07:29:08

标签: ruby-on-rails arrays ruby hash

大家好我无法找到问题的解决方案。所以我有一个类似下面的数组。

{
"9": [
    {
        "id": "9",
        "day": "2017-08-02",
        "voltage": "3397.1"
    },
    {
        "id": "9",
        "day": "2017-08-01",
        "voltage": "11518.67"
    },
    {
        "id": "9",
        "day": "2017-07-31",
        "voltage": "12835.5900000002"
    }
],
"11": [
    {
        "id": "11",
        "day": "2017-08-02",
        "voltage": "910.21"
    },
    {
        "id": "11",
        "day": "2017-08-01",
        "voltage": "3616.43"
    },
    {
        "id": "11",
        "day": "2017-07-31",
        "voltage": "2085.37"
    }
],
"12": [
    {
        "id": "12",
        "day": "2017-08-02",
        "voltage": "4793.96"
    },
    {
        "id": "12",
        "day": "2017-08-01",
        "voltage": "17762.2999999998"
    },
    {
        "id": "12",
        "day": "2017-07-31",
        "voltage": "18334.4000000001"
    }
  ]
}

现在我想做的是制作一个如下所示的数组

{
   "9": [
          "day": ["2017-08-02", "2017-08-01", "2017-07-31"],
          "voltage": ["3397.1", "11518.67", "12835.5900000002"]
        ],
   "11": [
          "day": ["2017-08-02","2017-08-01", "2017-07-31"]
          "voltage": ["910.21", "3616.43", "2085.37"]
         ] 
    ...
}

等等。 我试图使用.each.map方法迭代数组,但它不起作用。我在stackoverflow中搜索现有的解决方案,但没有任何帮助我。 有人可以帮我弄这个吗。 非常感谢提前。

3 个答案:

答案 0 :(得分:2)

如果您将hash定义为原始对象,则可以使用reduce执行此操作:

result = hash.reduce({}) do |memo, (key, vals)|
  memo[key] = {
    "day" => vals.map { |val| val[:day] },
    "voltage" => vals.map { |val| val[:voltage] }
  }
  memo
end

您也可以只使用each

result = {}
hash.each do |key, vals|
  result[key] = {
    "day" => vals.map { |val| val[:day] },
    "voltage" => vals.map { |val| val[:voltage] }
  }
end

答案 1 :(得分:0)

我不确定你是用JSON还是Ruby编写哈希,但是我没有时间将它重写为Ruby,我只是将它粘贴到一个脚本中,这使得所有的键都成为符号。

我相信这应该有效:

new_hash = {}
current_hash.each do |key, value_array|
  new_hash[key] ||= {}

  value_array.each do |values|
    new_values = values.dup
    new_values.delete(:id)

    new_values.each do |attribute_name, attribute_value|
      new_hash[key][attribute_name] ||= []
      new_hash[key][attribute_name] << attribute_value
    end
  end
end

这给了我这个结果:

{:"9"=>{:day=>["2017-08-02", "2017-08-01", "2017-07-31"], :voltage=>["3397.1", "11518.67", "12835.5900000002"]}, :"11"=>{:day=>["2017-08-02", "2017-08-01", "2017-07-31"], :voltage=>["910.21", "3616.43", "2085.37"]}, :"12"=>{:day=>["2017-08-02", "2017-08-01", "2017-07-31"], :voltage=>["4793.96", "17762.2999999998", "18334.4000000001"]}}

答案 2 :(得分:0)

我的另一个解决方案:)

对于Ruby 2.4.0:

hash.transform_values do |values| 
  values.each_with_object({}) do |value, memo| 
    memo[:day] ? memo[:day] << value[:day] : memo[:day] = [value[:day]]
    memo[:voltage] ? memo[:voltage] << value[:voltage] : memo[:voltage] = [value[:voltage]]
  end
end

早些时候:

hash.map do |key, values| 
  [
    key,
    values.each_with_object({}) do |value, memo| 
      memo[:day] ? memo[:day] << value[:day] : memo[:day] = [value[:day]]
      memo[:voltage] ? memo[:voltage] << value[:voltage] : memo[:voltage] = [value[:voltage]]
    end
  ]
end.to_h