hur man läser & tolka CSV-filer med Ruby

CSV står för ”kommaseparerade värden”.

det är ett vanligt dataformat som består av rader med värden separerade med kommatecken. Den används för att exportera & importera data.

till exempel:

du kan exportera dina Gmail-kontakter som en CSV-fil och du kan också importera dem med samma format.

så här ser en CSV-fil ut:

id,name1,chocolate2,bacon3,apple4,banana5,almonds

nu ska du lära dig hur du använder Ruby CSV-biblioteket för att läsa & skriv CSV-filer.

Ruby CSV-Tolkning

Ruby levereras med ett inbyggt CSV-bibliotek.

du kan läsa en fil direkt:

require 'csv'CSV.read("favorite_foods.csv")

eller så kan du tolka en sträng med CSV-data:

require 'csv'CSV.parse("1,chocolate\n2,bacon\n3,apple")

resultatet?

du får en tvådimensionell array där varje post är en rad i tabellen.

det ser ut så här:

, , , , , ]

du kan använda matrisindex som data för att arbeta med dessa data.

men det finns ett bättre sätt!

CSV-alternativ

om din fil har rubriker kan du berätta för CSV-tolkaren att använda dem.

table = CSV.parse(File.read("cats.csv"), headers: true)

nu istället för en flerdimensionell array får du ett CSV-tabellobjekt.

här är beskrivningen:

”a CSV::Table är en tvådimensionell datastruktur för att representera CSV-dokument. Tabeller kan du arbeta med data för rad eller kolumn, manipulera data, och även konvertera resultaten tillbaka till CSV.”

med tanke på en av dessa tabeller kan du få de data du behöver från vilken rad som helst.

exempel:

table# "1"table# "chocolate"

här 0 är den första raden, id & name är kolumnnamnen.

det finns två tabelllägen:

  • by_col
  • by_row

genom att ändra tabellläget (row som standard) kan du titta på data från olika vinklar.

till exempel:

table.by_col# table.by_col# 

här är 0 den första kolumnen, 1 är den andra kolumnen.

dessa två metoder returnerar en kopia av tabellen.

om du vill göra ändringar i originaltabellen kan du använda metoderna by_col! & by_row!.

detta kommer att bli mer minneseffektivt eftersom ingen kopia av tabellen skapas.

hur man använder CSV-omvandlare

du kanske har märkt att vi fick vår id kolumn som en rad strängar.

vad händer om vi behöver heltal?

du kan få dem genom att ringa to_i på varje sträng…

men det finns en genväg!

Ruby CSV-biblioteket implementerar något som kallas omvandlare.

en omvandlare omvandlar automatiskt värden åt dig.

till exempel:

CSV.parse("1,2,3,4,5")# ]CSV.parse("1,2,3,4,5", converters: :numeric)# ]

det finns 6 inbyggda omvandlare:

  • heltal
  • Float
  • numerisk (Float + heltal)
  • datum
  • DateTime
  • alla

men du kan också skapa dina egna konverterare.

så här gör du:

CSV::Converters = ->(value) { value.to_sym rescue value }

du kan använda din nya omvandlare så här:

CSV.parse("a,b,c", headers: false, converters: :symbol)# ]

hur man skapar en ny CSV-fil

förutom att kunna tolka & läsa CSV-filer på olika sätt kan du också skapa en CSV från början.

Detta är det enkla sättet:

cats = , , ]cats.map { |c| c.join(",") }.join("\n")

du kan också använda metoden generate :

CSV.generate do |csv| csv 

This prepares the data to be in the right format.

If you want to write to a file you'll have to use something like , or instead of you can use with a file name & write mode enabled.

CSV.open("cats.csv", "w") do |csv| csv 

Now you have a new CSV file!

CSV Gems & Performance

The built-in library is fine & it will get the job done.

But you can also find a few CSV parsing gems with different features.

For example, the gem will convert your CSV data into an array of hashes.

Example:

require 'smarter_csv'IntegerConverter = Object.newdef IntegerConverter.convert(value) Integer(value)endSmarterCSV.process('testing.csv', value_converters: { id: IntegerConverter })# 

här är en prestandajämförelse:

Comparison: CSV: 112.9 i/sSmarter CSV: 21.7 i/s - 5.21x slower Tabular: 17.3 i/s - 6.52x slower

sammanfattning

du har lärt dig att läsa & skriv CSV-filer i Ruby! Du har också lärt dig om omvandlare & alternativa Ruby gems för att bearbeta dina CSV-data.

om du vill bearbeta stora CSV-filer (> 10MB) kanske du vill använda metoden CSV.foreach(file_name) med ett block. Detta kommer att läsa en rad i taget & använder mycket mindre minne.

Vänligen dela den här artikeln så att fler kan hitta den!

Lämna ett svar

Din e-postadress kommer inte publiceras.