【问题标题】:How do I clean a data with hash and array mixed?如何清理混合了哈希和数组的数据?
【发布时间】:2012-09-10 06:30:13
【问题描述】:

我有一个这样的哈希数据:

{
  "current_condition" => [
    {
      "cloudcover"       => "100",
      "humidity"         => "100",
      "observation_time" => "05:44 AM",
      "precipMM"         => "0.0",
      "pressure"         => "1015",
      "temp_C"           => "14",
      "temp_F"           => "57",
      "visibility"       => "13",
      "weatherCode"      => "122",
      "weatherDesc"      => [
        {
          "value" => "Overcast"
        }
      ],
      "weatherIconUrl" => [
        {
          "value" => "http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0004_black_low_cloud.png"
        }
      ],
      "winddir16Point" => "NNW",
      "winddirDegree"  => "340",
      "windspeedKmph"  => "15",
      "windspeedMiles" => "9"
    }
  ], 
  "request" => [
    {
      "query" => "94127",
      "type"  => "Zipcode"
    }
  ],
  "weather" => [
    {
      "date"        => "2012-09-09",
      "precipMM"    => "0.0",
      "tempMaxC"    => "21",
      "tempMaxF"    => "69",
      "tempMinC"    => "12",
      "tempMinF"    => "53",
      "weatherCode" => "113",
      "weatherDesc" => [
        {
          "value" => "Sunny"
        }
      ],
      "weatherIconUrl" => [
        {
          "value" => "http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png"
        }
      ],
      "winddir16Point" => "W",
      "winddirDegree"  => "279",
      "winddirection"  => "W",
      "windspeedKmph"  => "23",
      "windspeedMiles" => "14"
    },
    {
      "date"        => "2012-09-10",
      "precipMM"    => "0.1",
      "tempMaxC"    => "20",
      "tempMaxF"    => "68",
      "tempMinC"    => "12",
      "tempMinF"    => "53",
      "weatherCode" => "119",
      "weatherDesc" => [
        {
          "value" => "Cloudy"
        }
      ],
      "weatherIconUrl" => [
        {
          "value" => "http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0003_white_cloud.png"
        }
      ],
      "winddir16Point" => "WSW",
      "winddirDegree"  => "252",
      "winddirection"  => "WSW",
      "windspeedKmph"  => "17",
      "windspeedMiles" => "11"
    }
  ]
}

一些哈希值只是字符串,其中一些是只有一个元素的数组,如下所示:

"weatherDesc"=>[{"value"=>"Cloudy"}]

我想让哈希中的所有元素都像这样:

"weatherDesc"=>{"value"=>"Cloudy"}

是否有简单的 Ruby 方法或单个循环可以做到这一点?还是我需要遍历每个 key-val 对来展平它?

--更新 -9-11-2012

感谢那些讨论并帮助我的人。这里更新一下,我刚发现数组里其实有一个hash值有2个对象,我修改了@iioiooioo这一行的代码

hash[k] = v.first if v.is_a?( Array ) && v.count == 1

--对此进行更多更新,上面的内容无法正常工作,因为数组中的数组没有被清理,因为没有处理具有 2 个元素的数组,这将结束对它的递归。我最终这样做了,这并不漂亮但是......

def arr_to_hash(a)
  hash = {}
  for i in 0..a.length-1
      hash[i.to_s] = a[i]
  end
  hash
end

def clean_it( hash )
  hash.each do |k,v|
  hash[k] = arr_to_hash v if v.is_a?( Array ) && v.count > 1
  hash[k] = v.first if v.is_a?( Array ) && v.count == 1
  clean_it( hash[k] ) if hash[k].is_a?( Hash )
  end
end

【问题讨论】:

  • 另外,如果您将重新格式化您的哈希以使其更具可读性,那将有所帮助。
  • @SergioTulentsev 我想这不是很简单。也许这个循环应该类似于 DFS 来展平散列中的每个数组,因为它是嵌套的。

标签: ruby arrays hash


【解决方案1】:

我不相信一个简单的循环就足够了,我认为你需要使用递归,就像这样:

a = {"current_condition"=> [{"cloudcover"=>"100", "humidity"=>"100", "observation_time"=>"05:44 AM", "precipMM"=>"0.0", "pressure"=>"1015", "temp_C"=>"14", "temp_F"=>"57", "visibility"=>"13", "weatherCode"=>"122", "weatherDesc"=>[{"value"=>"Overcast"}], "weatherIconUrl"=>[{"value"=>"http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0004_black_low_cloud.png"}], "winddir16Point"=>"NNW", "winddirDegree"=>"340", "windspeedKmph"=>"15", "windspeedMiles"=>"9"}], "request"=>[{"query"=>"94127", "type"=>"Zipcode"}], "weather"=>[{"date"=>"2012-09-09", "precipMM"=>"0.0", "tempMaxC"=>"21", "tempMaxF"=>"69", "tempMinC"=>"12", "tempMinF"=>"53", "weatherCode"=>"113", "weatherDesc"=>[{"value"=>"Sunny"}], "weatherIconUrl"=>[{"value"=>"http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png"}], "winddir16Point"=>"W", "winddirDegree"=>"279", "winddirection"=>"W", "windspeedKmph"=>"23", "windspeedMiles"=>"14"}, {"date"=>"2012-09-10", "precipMM"=>"0.1", "tempMaxC"=>"20", "tempMaxF"=>"68", "tempMinC"=>"12", "tempMinF"=>"53", "weatherCode"=>"119", "weatherDesc"=>[{"value"=>"Cloudy"}], "weatherIconUrl"=>[{"value"=>"http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0003_white_cloud.png"}], "winddir16Point"=>"WSW", "winddirDegree"=>"252", "winddirection"=>"WSW", "windspeedKmph"=>"17", "windspeedMiles"=>"11"}]}


def clean_it( hash )

 hash.each do |k,v|
  hash[k] = v.first if v.is_a?( Array )
  clean_it( hash[k] ) if hash[k].is_a?( Hash )
 end

end

clean_it( a )

p a

输出:

{"current_condition"=>{"cloudcover"=>"100", "humidity"=>"100", "observation_time"=>"05:44 AM", "precipMM"=>"0.0", "pressure"=>"1015", "temp_C"=>"14", "temp_F"=>"57", "visibility"=>"13", "weatherCode"=
>"122", "weatherDesc"=>{"value"=>"Overcast"}, "weatherIconUrl"=>{"value"=>"http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0004_black_low_cloud.png"}, "winddir16Point"=>"NNW", "wind
dirDegree"=>"340", "windspeedKmph"=>"15", "windspeedMiles"=>"9"}, "request"=>{"query"=>"94127", "type"=>"Zipcode"}, "weather"=>{"date"=>"2012-09-09", "precipMM"=>"0.0", "tempMaxC"=>"21", "tempMaxF"=>"
69", "tempMinC"=>"12", "tempMinF"=>"53", "weatherCode"=>"113", "weatherDesc"=>{"value"=>"Sunny"}, "weatherIconUrl"=>{"value"=>"http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0001_s
unny.png"}, "winddir16Point"=>"W", "winddirDegree"=>"279", "winddirection"=>"W", "windspeedKmph"=>"23", "windspeedMiles"=>"14"}}

【讨论】:

  • 哦,是的,递归!我应该想到的。而且您的代码非常清晰简洁。谢谢!!
  • 糟糕,我的错,实际上哈希的一个值是两个对象的数组。我想修改这条线会起作用。 hash[k] = v.first if v.is_a?( Array ) && v.count == 1
【解决方案2】:

我同意@iioiooioo,你绝对应该使用递归。我认为这应该做你想做的:

def collapse(obj)
  return obj unless obj.respond_to? :each
  if obj.is_a? Array
    ary = obj.map{ |elem| collapse elem }
    ary.first if ary.length == 1
  elsif obj.is_a? Hash
    obj.each { |key, val| obj[key] = collapse val }
    obj
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2016-03-30
    • 2019-03-22
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    相关资源
    最近更新 更多