2016-12-27 2 views
2

Я хочу преобразовать эту структуру хэш-рубина в массив хэшей. Конечная структура будет использоваться в 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 
    } 

To:

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]] 
    } 
] 

ответ

4

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]]} 

Остальные вычисления аналогичны.

+0

Спасибо за подробное объяснение. Попробуй попробовать – Mac

+1

Это было именно то, что я придумал, когда я попробовал. – Santhosh

+0

Спасибо @cary swoveland. Это тоже сработало. – Mac

2

Попробуйте это,

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 
+0

Спасибо, что это сработало !!! – Mac

Смежные вопросы