Ruby перебирает хеш хэша - PullRequest
0 голосов
/ 29 июня 2018

У меня есть следующий массив, и я пытаюсь отформатировать его для своих нужд.

consolidated = [
  {:name=>"Bob",   :details=>{"work"=>"Carpenter", "age"=>"26", "Experience"=>"6"} },
  {:name=>"Colin", :details=>{"work"=>"painting",  "age"=>"20", "Experience"=>"4"} }
]

Я пытаюсь отформатировать его как показано ниже:

Bob    work         Carpenter
       age          26
       Experience   6

Colin  work         painting
       age          20
       Experience   4

Я попробовал следующее:

require 'csv'
CSV.open("output.csv", "wb") do |csv|
  csv << ["name", "nature", "details"]
  consolidated.each do |val|
    csv << [val[:name], val[:details]]
  end
end
  #=> [{:name=>"Bob",   :details=>{"work"=>"Carpenter", "age"=>"26", "Experience"=>"6"}},
  #    {:name=>"Colin", :details=>{"work"=>"painting", "age"=>"20", "Experience"=>"4"}}]

но печатает следующее

name      nature                                                  details

Bob      "work"=>"Carpenter", "age"=>"26", "Experience"=>"6"

Colin    "work"=>"painting", "age"=>"20", "Experience"=>"4"

Я не совсем уверен, как перебрать хэш из 1-го цикла только для получения ожидаемого формата.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

Вот кое-что, с чего можно начать:

require 'csv'
data = [
  {:name => "Bob", :details=>{"work"=>"Carpenter", "age"=>"26", "Experience"=>"6"}},
  {:name => "Colin", :details=>{"work"=>"painting", "age"=>"20", "Experience"=>"4"}}
]

str = CSV.generate do |csv|
  data.each do |datum|
    datum[:details].each do |detail_key, detail_value|
      csv << [datum[:name], detail_key, detail_value]
    end
  end
end

puts str
# >> Bob,work,Carpenter
# >> Bob,age,26
# >> Bob,Experience,6
# >> Colin,work,painting
# >> Colin,age,20
# >> Colin,Experience,4

Просто переберите все детали и создайте новую строку для каждой пары ключ-значение, добавив имя человека.

Это даст вам почти , что вам нужно. Отсутствие только пустых строк между разделами и имя человека дублируется в каждой строке. Это будет ваша домашняя работа, чтобы узнать, как добавить эти улучшения.

0 голосов
/ 29 июня 2018

Вам нужно перебрать встроенный хеш с помощью each_pair итератора. Как то так:

data = {:name => "Bob", :details=>{"work"=>"Carpenter", "age"=>"26", "Experience"=>"6"}}

CSV.open("output.csv", "wb") do |csv|

  csv << ["name", "nature", "details"]

  data.each do |val|

    csv << [ val[:name], val[:details]['work'] ]

    data[:details].each_pair do |key, value]

      # here we have to drop the first pair because i've used it earlier 
      next if key == 'work'

      csv << [ "", key, value ]

    end

  end

end
0 голосов
/ 29 июня 2018

Я не знаю о генерации CSV (поэтому, если она работает так, как вы написали), вы можете выполнить итерации своего объекта следующим образом:

consolidated = [{:name => "Bob", :details=>{"work"=>"Carpenter", "age"=>"26", "Experience"=>"6"}}, {:name => "Colin", :details=> {"work"=>"painting", "age"=>"20", "Experience"=>"4"}}]


CSV.open("output.csv", "wb") do |csv|
  csv << ["name", "nature", "details"]

  consolidated.each do |val|
    details = val[:details]
    nature_1 = details.keys.first
    detail_1 = details.delete(nature_1)
    csv << [val[:name], nature_1, detail_1]

    details.each do |k, v|
      csv << [nil, k, v]
    end
  end
end

Примечание: Это приведет к повреждению исходного массива данных consolidated. Итак, если вы хотите сохранить его, dup сначала. Или измените логику, чтобы не удалять первое значение ключа из val[:details].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...