code

헤더 필드가있는 CSV 파일을 각 행의 속성으로 구문 분석

codestyles 2020. 11. 23. 08:13
반응형

헤더 필드가있는 CSV 파일을 각 행의 속성으로 구문 분석


CSV 파일을 구문 분석하여 각 행이 개체의 헤더 행이 개체의 속성 이름 인 개체처럼 처리되도록하고 싶습니다. 나는 이것을 쓸 수 있지만 이미 거기에 있다고 확신합니다.

내 CSV 입력은 다음과 같습니다.

"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6

코드는 다음과 같습니다.

CSV.open('my_file.csv','r') do |csv_obj|
  puts csv_obj.foo   #prints 1 the 1st time, "blah" 2nd time, etc
  puts csv.bar       #prints 2 the first time, 7 the 2nd time, etc
end

Ruby의 CSV 모듈을 사용하면 색인으로 만 필드에 액세스 할 수 있다고 생각합니다. 위의 코드가 좀 더 읽기 쉬울 것이라고 생각합니다. 어떤 아이디어?


Ruby 1.9 이상을 사용하면 색인 생성이 가능한 객체를 얻을 수 있습니다.

CSV.foreach('my_file.csv', :headers => true) do |row|
  puts row['foo'] # prints 1 the 1st time, "blah" 2nd time, etc
  puts row['bar'] # prints 2 the first time, 7 the 2nd time, etc
end

점 구문은 아니지만 숫자 인덱스보다 작업하는 것이 훨씬 좋습니다.

제쳐두고, Ruby 1.8.x의 경우 FasterCSV 는 위의 구문을 사용하는 데 필요한 것입니다.


다음은 Ruby 1.9를 사용하는 기호 구문의 예입니다. 아래 예제에서 코드는 Rails db 디렉토리에서 data.csv라는 CSV 파일을 읽습니다.

:headers => true첫 번째 행을 데이터 행 대신 헤더로 처리합니다. :header_converters => :symbolize매개 변수는 헤더 행의 각 셀을 Ruby 기호로 변환합니다.

CSV.foreach("#{Rails.root}/db/data.csv", {:headers => true, :header_converters => :symbol}) do |row|
  puts "#{row[:foo]},#{row[:bar]},#{row[:baz]}"
end

Ruby 1.8에서 :

require 'fastercsv'
CSV.foreach("#{Rails.root}/db/data.csv", {:headers => true, :header_converters => :symbol}) do |row|
  puts "#{row[:foo]},#{row[:bar]},#{row[:baz]}"
end

Poul (StackOverflow asker)에서 제공 한 CSV를 기반으로 위 예제 코드의 출력은 다음과 같습니다.

1,2,3
blah,7,blam
4,5,6

CSV 파일의 헤더에 사용 된 문자에 따라 CSV (FasterCSV)가 문자열 헤더를 기호로 변환 한 방법을 확인하기 위해 헤더를 출력해야 할 수 있습니다. 내에서 헤더 배열을 출력 할 수 있습니다 CSV.foreach.

row.headers

Ruby 2.3에서 해시를 쉽게 얻을 수 있습니다.

CSV.foreach('my_file.csv', headers: true, header_converters: :symbol) do |row|
  puts row.to_h[:foo]
  puts row.to_h[:bar]
end

토론에 꽤 늦었지만 몇 달 전에 https://github.com/vicentereig/virgola 에서 "CSV to object mapper"를 시작했습니다 .

CSV 콘텐츠가 주어지면 FooBar개체 배열에 매핑하는 것은 매우 간단합니다.

"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
require 'virgola'

class FooBar
  include Virgola

  attribute :foo
  attribute :bar
  attribute :baz
end

csv = <<CSV
"foo","bar","baz"
1,2,3
"blah",7,"blam"
4,5,6
CSV

foo_bars = FooBar.parse(csv).all
foo_bars.each { |foo_bar| puts foo_bar.foo, foo_bar.bar, foo_bar.baz }

나는이 질문을 몇 가지 빈도로 쳤기 때문에 :

array_of_hashmaps = CSV.read("path/to/file.csv", headers: true)
puts array_of_hashmaps.first["foo"] # 1

이것은 전체 파일을 훑어보고 싶을 때 비 블록 버전입니다.

참고 URL : https://stackoverflow.com/questions/3717464/parse-csv-file-with-header-fields-as-attributes-for-each-row

반응형