I have a hash data like this:
{
"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"
}
]
}
Some of the hash values are just strings, some of them are arrays with only one element like this:
"weatherDesc"=>[{"value"=>"Cloudy"}]
I want to make all the elements like this in the hash to be like:
"weatherDesc"=>{"value"=>"Cloudy"}
Is there an easy Ruby method, or a single loop that can do this? Or do I need to loop through each key-val pair to flatten this?
–update -9-11-2012
Thanks for those who discussed and helped me out. Here’s an update, I just found that there’s actually one hash value has 2 objects in the array, I modified the @iioiooioo ‘s code in this line
hash[k] = v.first if v.is_a?( Array ) && v.count == 1
–more update on this, that above doesn’t work correctly since there are arrays in the array who doesn’t get cleaned since the array with 2 elements is not processed, which would end the recursion on it. I end up doing this, which is not pretty but…
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
I do not believe a simple loop will suffice, I think you need to use recursion, like so:
Outputs: