将哈希更改为哈希数组
Changing a hash to an array of hash
我想将这个 ruby 哈希结构转换为一个哈希数组。结束结构将在图表中使用 api,提前致谢
发件人:
data =
{
["Transportations", "Not-Approved"] => 350,
["Transportations", "Approved"] => 160,
["Communications", "Not-Approved"] => 300,
["Communications","Approved"] => 80,
["Rentals","Not-Approved"] => 50,
["Rentals", "Approved"] => 145,
["Salaries","Not-Approved"] => 150,
["Salaries", "Approved"] => 310
}
收件人:
data = [
{
name: "Transportations",
data: [["Not-Approved", 350], ["Approved", 160]]
},
{
name: "Communications",
data: [["Not-Approved", 300], ["Approved", 80]]
},
{
name: "Rentals",
data: [["Not-Approved", 50], ["Approved", 145]]
},
{
name: "Salaries",
data: [["Not-Approved", 150], ["Approved", 310]]
}
]
试试这个,
h = Hash.new { |h, k| h[k] = { name: k, data: {} }}
data.each { |(name, each), value| h[name][:data][each] = value };
h.values.each { |each| each[:data] = each[:data].to_a }
array = h.values
代码
def rearrange(data)
data.group_by { |k,_| k.first }.map { |name, arr|
{ name: name, data: arr.map { |(_,outcome), val| [outcome, val] } } }
end
例子
data = {
["Transportations", "Not-Approved"] => 350,
["Transportations", "Approved"] => 160,
["Communications", "Not-Approved"] => 300,
["Communications","Approved"] => 80,
["Rentals","Not-Approved"] => 50,
["Rentals", "Approved"] => 145,
["Salaries","Not-Approved"] => 150,
["Salaries", "Approved"] => 310
}
rearrange(data)
#=> [{:name=>"Transportations",
# :data=>[["Not-Approved", 350], ["Approved", 160]]},
# {:name=>"Communications",
# :data=>[["Not-Approved", 300], ["Approved", 80]]},
# {:name=>"Rentals",
# :data=>[["Not-Approved", 50], ["Approved", 145]]},
# {:name=>"Salaries",
# :data=>[["Not-Approved", 150], ["Approved", 310]]}
# ]
说明
第一步如下
h = data.group_by { |k,_| k.first }
#=> { "Transportations"=>[
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ],
# "Communications"=>[
# [["Communications", "Not-Approved"], 300],
# [["Communications", "Approved"], 80]
# ],
# "Rentals"=>[
# [["Rentals", "Not-Approved"], 50],
# [["Rentals", "Approved"], 145]
# ],
# "Salaries"=>[
# [["Salaries", "Not-Approved"], 150],
# [["Salaries", "Approved"], 310]
# ]
# }
Enumerable#group_by 的第二个块变量保存键的值(键是第一个块变量)。例如,当键为 ["Transportations", "Not-Approved"]
时,值为 350
。我把block变量_
(一个有效的局部变量)赋值给了值,主要是通知reader在block计算中没有用到
要理解第二步,h
的键值对的映射,先定义
enum = h.map
#=> #<Enumerator:
# {"Transportations"=>[
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ], "Communications"=>[
# ...
# [["Salaries", "Approved"], 310]]}:map>
生成enum
的第一个元素并传递给块,块变量使用并行赋值.
赋值
name, arr = enum.next
#=> ["Transportations", [
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ]
# ]
name
#=> "Transportations"
arr
#=> [
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ]
然后进行map
的分块计算。首先计算
a = arr.map { |(_,outcome), val| [outcome, val] }
#=> [["Not-Approved", 350], ["Approved", 160]]
然后构造`"Transportation".
的散列
{ name: name, data: a }
#=> {:name=>"Transportations",
# :data=>[["Not-Approved", 350], ["Approved", 160]]}
其余计算类似。
我想将这个 ruby 哈希结构转换为一个哈希数组。结束结构将在图表中使用 api,提前致谢
发件人:
data =
{
["Transportations", "Not-Approved"] => 350,
["Transportations", "Approved"] => 160,
["Communications", "Not-Approved"] => 300,
["Communications","Approved"] => 80,
["Rentals","Not-Approved"] => 50,
["Rentals", "Approved"] => 145,
["Salaries","Not-Approved"] => 150,
["Salaries", "Approved"] => 310
}
收件人:
data = [
{
name: "Transportations",
data: [["Not-Approved", 350], ["Approved", 160]]
},
{
name: "Communications",
data: [["Not-Approved", 300], ["Approved", 80]]
},
{
name: "Rentals",
data: [["Not-Approved", 50], ["Approved", 145]]
},
{
name: "Salaries",
data: [["Not-Approved", 150], ["Approved", 310]]
}
]
试试这个,
h = Hash.new { |h, k| h[k] = { name: k, data: {} }}
data.each { |(name, each), value| h[name][:data][each] = value };
h.values.each { |each| each[:data] = each[:data].to_a }
array = h.values
代码
def rearrange(data)
data.group_by { |k,_| k.first }.map { |name, arr|
{ name: name, data: arr.map { |(_,outcome), val| [outcome, val] } } }
end
例子
data = {
["Transportations", "Not-Approved"] => 350,
["Transportations", "Approved"] => 160,
["Communications", "Not-Approved"] => 300,
["Communications","Approved"] => 80,
["Rentals","Not-Approved"] => 50,
["Rentals", "Approved"] => 145,
["Salaries","Not-Approved"] => 150,
["Salaries", "Approved"] => 310
}
rearrange(data)
#=> [{:name=>"Transportations",
# :data=>[["Not-Approved", 350], ["Approved", 160]]},
# {:name=>"Communications",
# :data=>[["Not-Approved", 300], ["Approved", 80]]},
# {:name=>"Rentals",
# :data=>[["Not-Approved", 50], ["Approved", 145]]},
# {:name=>"Salaries",
# :data=>[["Not-Approved", 150], ["Approved", 310]]}
# ]
说明
第一步如下
h = data.group_by { |k,_| k.first }
#=> { "Transportations"=>[
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ],
# "Communications"=>[
# [["Communications", "Not-Approved"], 300],
# [["Communications", "Approved"], 80]
# ],
# "Rentals"=>[
# [["Rentals", "Not-Approved"], 50],
# [["Rentals", "Approved"], 145]
# ],
# "Salaries"=>[
# [["Salaries", "Not-Approved"], 150],
# [["Salaries", "Approved"], 310]
# ]
# }
Enumerable#group_by 的第二个块变量保存键的值(键是第一个块变量)。例如,当键为 ["Transportations", "Not-Approved"]
时,值为 350
。我把block变量_
(一个有效的局部变量)赋值给了值,主要是通知reader在block计算中没有用到
要理解第二步,h
的键值对的映射,先定义
enum = h.map
#=> #<Enumerator:
# {"Transportations"=>[
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ], "Communications"=>[
# ...
# [["Salaries", "Approved"], 310]]}:map>
生成enum
的第一个元素并传递给块,块变量使用并行赋值.
name, arr = enum.next
#=> ["Transportations", [
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ]
# ]
name
#=> "Transportations"
arr
#=> [
# [["Transportations", "Not-Approved"], 350],
# [["Transportations", "Approved"], 160]
# ]
然后进行map
的分块计算。首先计算
a = arr.map { |(_,outcome), val| [outcome, val] }
#=> [["Not-Approved", 350], ["Approved", 160]]
然后构造`"Transportation".
的散列{ name: name, data: a }
#=> {:name=>"Transportations",
# :data=>[["Not-Approved", 350], ["Approved", 160]]}
其余计算类似。