-1

so I have an array of hashes (json format) that look like this

[
  {
    "2017-04-01 00:00:00 UTC": 100.992226272734
  },
  {
    "2017-03-01 00:00:00 UTC": 3.0594465818934964
  },
]

now i want to map each key into new value with a static key date:, its came a same way with value, each value has new static key value: , what i mean is those hash now look like :

[
{
  "date": "2017-04-01 00:00:00 UTC",
  "value": 100.992226272734
},
{
 "date": "2017-03-01 00:00:00 UTC",
  "value": 3.0594465818934964
}
]

can anyone help me show the best way to do that ?

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Please read "[ask]" including the linked pages, "[mcve]" and "[How much research effort is expected of Stack Overflow users?](http://meta.stackoverflow.com/questions/261592)". We'd like to see evidence of your effort. What did you try? Did you search and not find anything? Did you find stuff but it didn't help? Did you try writing code? If not, why? If so, what is the smallest code example that shows what you tried and why didn't it work? Without that it looks like you didn't try and want us to write it for you. – the Tin Man Apr 11 '17 at 18:33

3 Answers3

1
require 'json'

Assuming

arr = [{ "2017-04-01 00:00:00 UTC": 100.992226272734 },
       { "2017-03-01 00:00:00 UTC": 3.0594465818934964 }]

the JSON object (string) is

json = arr.to_json
  #=> "[{\"2017-04-01 00:00:00 UTC\":100.992226272734},\
  #     {\"2017-03-01 00:00:00 UTC\":3.0594465818934964}]" 

which we can convert to the desired array of hashes thusly:

JSON.parse(json).map do |g|
  k, v = g.first
  { "date"=> k, "value"=>v }
end
  #=> [{"date"=>"2017-04-01 00:00:00 UTC", "value"=>100.992226272734}, 
  #    {"date"=>"2017-03-01 00:00:00 UTC", "value"=>3.0594465818934964}] 
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100
  • OP says their data is in JSON format, so probably `to_s` isn't necessary. – Jordan Running Apr 11 '17 at 18:54
  • @Jordan, what does "JSON" format mean? If the object shown by the OP is an array, I would think the fact that it was obtained by parsing a JSON string is irrelevant. If it's a string why is it not enclosed in single quotes? If you suspect I don't know much about JSON you are correct. – Cary Swoveland Apr 11 '17 at 19:05
  • 1
    OP indicating "json format" led me to guess that the subsequent code block contains JSON-serialized data (a JSON array containing JSON objects, to be specific), not Ruby code. I could be wrong. But if I'm not, and it is JSON and not Ruby code, then calling `JSON.parse(text)` where `text` is a String containing that JSON will yield a Ruby Array containing Hashes with String keys and not Symbol keys. But, again, I could be wrong. – Jordan Running Apr 11 '17 at 19:12
1

If you want to do exactly what you described, I'd say that @Cary's answer works just fine.

I just would like to add that a slightly different format might be easier and faster to work with (provided date fields are unique). You could just merge every hash together:

require 'json'

json_data = %q([
  {
    "2017-04-01 00:00:00 UTC": 100.992226272734
  },
  {
    "2017-03-01 00:00:00 UTC": 3.0594465818934964
  }
])

hashes = JSON.parse(json_data)
date_and_values = hashes.inject(&:merge)
# {"2017-04-01 00:00:00 UTC"=>100.992226272734, "2017-03-01 00:00:00 UTC"=>3.0594465818934964}

All the information is still here, but it's much easier to access :

date_and_values.keys
# ["2017-04-01 00:00:00 UTC", "2017-03-01 00:00:00 UTC"]
date_and_values.values
# [100.992226272734, 3.0594465818934964]
date_and_values["2017-04-01 00:00:00 UTC"]
# 100.992226272734
Community
  • 1
  • 1
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
0

Just use #map and make a new hash for each element. Map operations are useful when you want to present data that exists in your collection in a different way (as you do in your question).

original = [
  {
    "2017-04-01 00:00:00 UTC" => 100.992226272734
  },
  {
    "2017-03-01 00:00:00 UTC" => 3.0594465818934964
  },
]

mapped = original.map do |h|
  Hash[%w(date value).zip(h.keys + h.values)]
end

mapped looks like this:

[
    {"date" => "2017-04-01 00:00:00 UTC", "value"=>100.992226272734}, 
    {"date" => "2017-03-01 00:00:00 UTC", "value"=>3.0594465818934964}
]

You should look through the Enumerable API to see what other operations you can perform on collections when tasked with similar problems.

David S.
  • 730
  • 1
  • 7
  • 23
  • 1
    Note that since you are using JSON notation on a Ruby hash the keys are automatically cast to symbols. You should use hashrockets (`=>`) instead to get the right output. – max Apr 11 '17 at 18:35
  • 1
    The body of your block seems both overly clever and needlessly verbose. Why not `d,v = h.first; { "date" => d, "value" => v }`? https://repl.it/HFdC – Jordan Running Apr 11 '17 at 18:50