diff options
-rw-r--r-- | lib/pure/parsecsv.nim | 73 | ||||
-rw-r--r-- | web/news/version_0_15_released.rst | 2 |
2 files changed, 75 insertions, 0 deletions
diff --git a/lib/pure/parsecsv.nim b/lib/pure/parsecsv.nim index bb291bcbc..77b145a73 100644 --- a/lib/pure/parsecsv.nim +++ b/lib/pure/parsecsv.nim @@ -25,6 +25,28 @@ ## echo "##", val, "##" ## close(x) ## +## For CSV files with a header row, the header can be read and then used as a +## reference for item access with `rowEntry <#rowEntry.CsvParser.string>`_: +## +## .. code-block:: nim +## import parsecsv +## import os +## # Prepare a file +## var csv_content = """One,Two,Three,Four +## 1,2,3,4 +## 10,20,30,40 +## 100,200,300,400 +## """ +## writeFile("temp.csv", content) +## +## var p: CsvParser +## p.open("temp.csv") +## p.readHeaderRow() +## while p.readRow(): +## echo "new row: " +## for col in items(p.headers): +## echo "##", col, ":", p.rowEntry(col), "##" +## p.close() import lexbase, streams @@ -37,6 +59,9 @@ type sep, quote, esc: char skipWhite: bool currRow: int + headers*: seq[string] ## The columns that are defined in the csv file + ## (read using `readHeaderRow <#readHeaderRow.CsvParser>`_). + ## Used with `rowEntry <#rowEntry.CsvParser.string>`_). CsvError* = object of IOError ## exception that is raised if ## a parsing error occurs @@ -177,6 +202,22 @@ proc close*(my: var CsvParser) {.inline.} = ## closes the parser `my` and its associated input stream. lexbase.close(my) +proc readHeaderRow*(my: var CsvParser) = + ## Reads the first row and creates a look-up table for column numbers + ## See also `rowEntry <#rowEntry.CsvParser.string>`_. + var present = my.readRow() + if present: + my.headers = my.row + +proc rowEntry*(my: var CsvParser, entry: string): string = + ## Reads a specified `entry` from the current row. + ## + ## Assumes that `readHeaderRow <#readHeaderRow.CsvParser>`_ has already been + ## called. + var index = my.headers.find(entry) + if index >= 0: + result = my.row[index] + when not defined(testing) and isMainModule: import os var s = newFileStream(paramStr(1), fmRead) @@ -189,3 +230,35 @@ when not defined(testing) and isMainModule: echo "##", val, "##" close(x) +when isMainModule: + import os + import strutils + block: # Tests for reading the header row + var content = "One,Two,Three,Four\n1,2,3,4\n10,20,30,40,\n100,200,300,400\n" + writeFile("temp.csv", content) + + var p: CsvParser + p.open("temp.csv") + p.readHeaderRow() + while p.readRow(): + var zeros = repeat('0', p.currRow-2) + doAssert p.rowEntry("One") == "1" & zeros + doAssert p.rowEntry("Two") == "2" & zeros + doAssert p.rowEntry("Three") == "3" & zeros + doAssert p.rowEntry("Four") == "4" & zeros + p.close() + + when not defined(testing): + var parser: CsvParser + parser.open("temp.csv") + parser.readHeaderRow() + while parser.readRow(): + echo "new row: " + for col in items(parser.headers): + echo "##", col, ":", parser.rowEntry(col), "##" + parser.close() + removeFile("temp.csv") + + # Tidy up + removeFile("temp.csv") + diff --git a/web/news/version_0_15_released.rst b/web/news/version_0_15_released.rst index 4cc5fb2a7..ad3119cca 100644 --- a/web/news/version_0_15_released.rst +++ b/web/news/version_0_15_released.rst @@ -14,6 +14,8 @@ Changes affecting backwards compatibility Library Additions ----------------- +- Added ``readHeaderRow`` and ``rowEntry`` to ``parsecsv.nim`` to provide + a lightweight alternative to python's ``csv.DictReader``. Compiler Additions ------------------ |