2013-10-09 3 views
1

Я импортировать файл CSV, который содержит поля, которые должны быть преобразованы следующим образом:Пользовательские рубин CSV преобразователи для нескольких полей

  • «True» (строка) -> истина (булево)
  • «Ложное "(строка) -> false (boolean)
  • «% m /% d /% Y »(формат строки) -> Объект даты
  • «% m /% d /% Y% I:% M:% S% p "(формат строки) -> Объект DateTime

Преобразователи CSV по умолчанию не соответствуют полям Date и DateTime. Этот метод ниже работает, но задайтесь вопросом, есть ли лучший способ, возможно, переопределив шаблон соответствия, используемый преобразователями?

require 'csv' 
require 'date' 

src = <<csv 
active,date_created,date_modified 
"True","03/12/2012","03/12/2012 2:14:23 PM" 
"False","01/25/2011","03/12/2013 3:14:27 AM" 
csv 

CSV::Converters[:my_converters] = lambda{|field| 
    begin 
    case field.to_s 
     when "True" 
     true 
     when "False" 
     false 
     when /^\d{2}\/\d{2}\/\d{4}$/ 
     Date.strptime(field,"%m/%d/%Y") 
     else 
     DateTime.strptime(field,"%m/%d/%Y %I:%M:%S %p") 
     end 
    rescue ArgumentError 
    field 
    end 
} 

csv = CSV(src, :headers => true, :converters => [:my_converters]) 
csv.each{|row| puts row} 

правда, 2012-03-12,2012-03-12T14: 14: 23 + 00: 00

ложь, 2011-01-25,2013-03-12T03: 14: 27+ 00:00

ответ

1

Это правильный способ делать вещи, если преобразователи по умолчанию недостаточны. Мое единственное предложение состояло в том, чтобы разделить ваши конвертеры на разные lambdas, поскольку библиотека CSV уже предназначена для тестирования каждого поля по сравнению с массивом преобразователей (что делает ваш case избыточным).

Но если это простой одноразовый скрипт, то у вас достаточно.

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