Natknąłem się dziś na ciekawy problem. Parsuję spore raporty, w których jedna z kolumn na wartość typu "1234_5678". Dla wydajności korzystam z klasy CSV z opcją converters: :all. Do dziś byłem przekonany, że oddzielanie cyfr podkreślnikiem to super rzecz, ale teraz serdecznie nienawidzę tej opcji. Macie może jakiś pomysł jak ominąć konwersję dla jednej kolumny? Lub napisać konwerter, który będzie wydajny?
Tak jest teraz:
“12341234” -> CSV#converters -> 12341234
“1234_1234” -> CSV#converters -> 12341234 To chcę, aby było:
“12341234” -> CSV#converters -> 12341234
“1234_1234” -> CSV#converters -> “1234_1234”
CSV::Converters[:abc] = lambda do |s|
s.gsub('_', 'skomplikowanystystemzamiennikow')
end
CSV::Converters[:cba] = lambda do |s|
s.gsub('skomplikowanystystemzamiennikow', '_')
end
i potem: :converters => [:abc, :all, :cba],
Czyli na początek pozbywamy się _ - potem robimy konwersję :all - i na koniec przywracamy _
Tylko tam musisz sprawdzić czy zawsze s będzie miało gsub - bo nie wiem czy tam zawsze jest string.
Dzięki Jacki za poświęcenie czasu. Ominąłem problem wykorzystując kod z SmarterCSV:
CSV::Converters[:fast_integer] = lambda do |field|
field.match(/^[+-]?\d+$/) ? field.to_i : field
end
CSV::Converters[:fast_float] = lambda do |field|
field.match(/^[+-]?\d+\.\d+$/) ? field.to_f : field
end
Działa zadziwiająco dobrze. Jedyne czego teraz się obawiam to zlokalizowane floaty. W moim systemie taka sytuacja raczej nie wystąpi, ale lepiej dmuchać na zimne.
Gdyby ktoś z Was chciał przyspieszyć parsowanie CSV to polecam własne convertery. U mnie wynik był w granicach 5x.