Rubyを使ったデジタル化

以下のようなCSVファイル、またはTextファイルの情報をRubyのオブジェクトに変換する。

parent child
id1 value0
value1
value2
id2 value3
value4
value5
value6
value7
id3 value8
value9

次のRubyスクリプトで、Rubyオブジェクト(Array)に変換する。

require "csv"
data = CSV.read("file.csv", encoding: "BOM|UTF-8", headers: true).map(&:to_h)

parentごとに、childをまとめる:Hashを使用した場合

all_hash = {}
tmp_id = ""

data.each do |hash|
  parent = hash["parent"]
  child = hash["child"]

  if parent.nil?
    all_hash[tmp_id] << hash["child"]
  else
    tmp_id = parent
    all_hash[tmp_id] = [child]
  end
end

Hashのキーにparent、バリューに複数のchildが入っていることがわかる。

all_hash
=> 
{"id1"=>["value0", "value1", "value2"],
 "id2"=>["value3", "value4", "value5", "value6", "value7"],
 "id3"=>["value8", "value9"]}

parentごとに、childをまとめる:Classを使用した場合

class Family
  attr_accessor :children

  def initialize(parent)
    @parent = parent
    @children = []
  end
end

arr = []
data.each do |hash|
  parent = hash["parent"]
  if parent.nil?
    arr.last.children << hash["child"]
  else
    arr << Family.new(parent)
  end
end

Familyオブジェクトが親子要素ごとに格納されていることがわかる。

arr
=> 
[#<Family:0x0000000102a26f68
  @children=["value1", "value2"],
  @parent="id1">,
 #<Family:0x0000000102a26ea0
  @children=["value4", "value5", "value6", "value7"],
  @parent="id2">,
 #<Family:0x0000000102a26e00
  @children=["value9"],
  @parent="id3">]