C ода
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
. Я присвоил значение блока _
(действительная локальная переменная), в основном, чтобы сообщить читателю, что он не используется при расчете блока.
Чтобы понять второй шаг, отображение ключа пары значений 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]]
Затем создайте хэш для `` Транспортировка ''.
{ name: name, data: a }
#=> {:name=>"Transportations",
# :data=>[["Not-Approved", 350], ["Approved", 160]]}
Остальные вычисления аналогичны.
Спасибо за подробное объяснение. Попробуй попробовать – Mac
Это было именно то, что я придумал, когда я попробовал. – Santhosh
Спасибо @cary swoveland. Это тоже сработало. – Mac