Ruby CSVで重複したヘッダーを置換
10774 ワード
はじめに
1行目をヘッダーとするCSVファイルで、重複しているものをRubyで取り込む機会がありました。
その際、重複しているヘッダーの項目も取得できるように重複しているものを置換する方法を調査しました。
(最終的にはCSVファイルのヘッダーを重複しないように出力してもらうようになったので、実際に使用することはなかったです)
環境
- Ruby 3.1.1
コード
require 'csv'
raw_data = "a,b,b,c,d,,e\naa,bb,bbbb,cc,dd,,ee"
csv_table = CSV.new(raw_data, headers: :first_row).read
headers = csv_table.headers
duplicated_headers = headers.select { |header| headers.count(header) > 1 }.uniq
convert_header_map = {}
convert_header_seq = {}
headers.each_with_index do |header, index|
if duplicated_headers.include?(header)
seq = convert_header_seq[header]
seq = seq.nil? ? 1 : seq + 1
convert_header_map[index] = "#{header}_#{seq}"
convert_header_seq[header] = seq
end
end
header_converters = [lambda { |field, field_info| convert_header_map[field_info.index] || field }]
csv_table2 = CSV.new(raw_data, headers: :first_row, header_converters: header_converters).read
irb(main):068:0> csv_table2[0]
=> #<CSV::Row "a":"aa" "b_1":"bb" "b_2":"bbbb" "c":"cc" "d":"dd" nil:nil "e":"ee">
irb(main):069:0> csv_table2[0]['b_1']
=> "bb"
irb(main):070:0> csv_table2[0]['b_2']
=> "bbbb"
内容
1回CSVを読み込み、重複しているヘッダーを抽出
csv_table = CSV.new(raw_data, headers: :first_row).read
headers = csv_table.headers
duplicated_headers = headers.select { |header| headers.count(header) > 1 }.uniq
重複しているヘッダーに対して、変換用のハッシュを生成
convert_header_map = {}
convert_header_seq = {}
headers.each_with_index do |header, index|
if duplicated_headers.include?(header)
seq = convert_header_seq[header]
seq = seq.nil? ? 1 : seq + 1
convert_header_map[index] = "#{header}_#{seq}"
convert_header_seq[header] = seq
end
end
変換用ハッシュを使用し、ヘッダーを変換を指定してCSVを再度読み込み
ヘッダーの変換はheader_converters
で指定
header_converters = [lambda { |field, field_info| convert_header_map[field_info.index] || field }]
csv_table2 = CSV.new(raw_data, headers: :first_row, header_converters: header_converters).read
まとめ
1度CSVを読み込んだあと、ヘッダーが重複する場合はヘッダーを置換する対象を取得し、再度CSVの読み込みでヘッダーを置換する方法にしてみました。
2回CSVの全体を読み込んでいるので、もっとよい方法があると思いますがパッと見当たらなかったので、一旦はこの方法で。
Author And Source
この問題について(Ruby CSVで重複したヘッダーを置換), 我々は、より多くの情報をここで見つけました https://zenn.dev/greendrop/articles/109404ccec6411著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol