I've written an API to organize my daily user data.
The origin format is like
"dau": {
"2017-05-02": 1,
"2017-05-04": 2,
"2017-05-05": 2,
}
"new_user": {
"2017-05-02": 1,
"2017-05-04": 0,
"2017-05-07": 0,
}
It's hard to display in HTML table row by row.
Therefore, I want the format to become this one.
However, I have no idea how to deal with.
info: {
"2017-05-02": {
dau: 1,
new_user: 1
},
"2017-05-04": {
dau: 2,
new_user: 0
},
"2017-05-05": {
dau: 2
},
"2017-05-07": {
new_user: 0
}
}
suppose you have data
, then
(data['dau'].keys + data['new_user'].keys).uniq.map { |k| [k, { dau: data['dau'][k].to_i, new_user: data['new_user'][k].to_i } ] }.to_h
and if you don't want default/0 values then,
(data['dau'].keys + data['new_user'].keys).uniq.map { |k| [k, { dau: data['dau'][k], new_user: data['new_user'][k] }.compact ] }.to_h
Output:
{
"2017-05-02" => {
:dau => 1,
:new_user => 1
},
"2017-05-04" => {
:dau => 2,
:new_user => 0
},
"2017-05-05" => {
:dau => 2
},
"2017-05-07" => {
:new_user => 0
}
}
Hope it helps..
keys = (dau.keys + new_user.keys).uniq
# [:"2017-05-02", :"2017-05-04", :"2017-05-05", :"2017-05-07"]
keys.each_with_object({}) do |key, result|
result[key] = {dau: dau[key], new_user: new_user[key] }.compact
end
# {:"2017-05-02"=>{:dau=>1, :new_user=>1},
# :"2017-05-04"=>{:dau=>2, :new_user=>0},
# :"2017-05-05"=>{:dau=>2},
# :"2017-05-07"=>{:new_user=>0}}
Here's an alternative with each_with_object
. It should work with any number of keys:
data = {"dau": {
"2017-05-02": 1,
"2017-05-04": 2,
"2017-05-05": 2
},
"new_user": {
"2017-05-02": 1,
"2017-05-04": 0,
"2017-05-07": 0
}
}
info = Hash.new { |h, k| h[k] = {} }
info = data.each_with_object(info) do |(key, sub_h), h|
sub_h.each do |date, i|
h[date][key] = i
end
end
p info
# {:"2017-05-02"=>{:dau=>1, :new_user=>1}, :"2017-05-04"=>{:dau=>2, :new_user=>0}, :"2017-05-05"=>{:dau=>2}, :"2017-05-07"=>{:new_user=>0}}