csv
CSV and TSV parsing, writing and transformation.
Backend: native — stdlib/csv.so, built from stdlib/csv.cpp (a hand-written reader/writer) and stdlib/native_json.hpp. Import: import("csv") → global.csv.*
Rows are exchanged as JSON strings: arrays of arrays for positional access and arrays of objects for keyed access, so csv pairs naturally with json.
| Function | Signature | Returns |
|---|---|---|
readCSV | (str path) | Raw file content, or "ERROR: ..." |
writeCSV | (str path, str jsonRows, str headers) | "ok" or "ERROR: ..." |
buildCSV | (str jsonRows, str headers) | CSV text (no disk write) |
appendRow | (str csvStr, str jsonRow) | CSV text with one row appended |
parseRows | (str csvStr) | JSON array-of-arrays, header row included |
parseHeaders | (str csvStr) | JSON array of the header row |
parseToJson | (str csvStr) | JSON array of objects keyed by the header row |
getColumn | (str csvStr, str colName) | JSON array of the column's values |
getRow | (str csvStr, int rowIdx) | JSON array for data row rowIdx (0-based) |
rowCount | (str csvStr) | Data rows, excluding the header |
colCount | (str csvStr) | Columns in the header row |
hasColumn | (str csvStr, str colName) | 1 or 0 |
filterRows | (str csvStr, str colName, str value) | CSV text with matching rows only |
sortCSV | (str csvStr, str colName) | CSV text sorted ascending (lexicographic) |
sortCSVDesc | (str csvStr, str colName) | CSV text sorted descending |
columnStats | (str csvStr, str colName) | JSON {count, min, max, sum, mean} or {} |
toTSV | (str csvStr) | TSV text |
fromTSV | (str tsvStr) | CSV text |
readWithDelimiter | (str path, str delimiter) | Raw file content |
parseDelimited | (str csvStr, str delimiter) | JSON array of objects using a custom delimiter |
Dialect follows the standard csv format: , delimiter, " quoting with "" escaping, and \r\n line terminators on output. Non-string JSON values are rendered as compact JSON scalar text: null becomes an empty field, booleans become lowercase true / false, numbers use their JSON number text, and arrays/objects use compact JSON. Input accepts LF, CRLF, or bare CR record terminators; terminators embedded in quoted fields remain field data.
buildCSV and writeCSV use exactly the supplied header columns, in their given order. Missing object fields are empty and object fields not named in the header are ignored. Parsing into objects also follows header width: short rows are padded with empty strings and surplus cells are ignored; parseRows continues to preserve each input row's actual width.
Legacy aliases
Names from the earlier csv API, kept as forwarders:
| Alias | Equivalent |
|---|---|
parseCSV(csvStr) | parseToJson(csvStr) |
parseCSVRaw(csvStr) | parseRows(csvStr) |
readCSVRaw(path) | parseRows(readCSV(path)); "[]" when readCSV returns "ERROR: ..." |
csvColumn(csvStr, col) | getColumn(csvStr, col) |
csvRowCount(csvStr) | rowCount(csvStr) |
filterCSV(csvStr, col, value) | filterRows(csvStr, col, value) |
Three aliases have no single-op equivalent and are implemented natively:
| Function | Signature | Returns |
|---|---|---|
csvHeaders | (str csvStr) | Header names joined by commas |
csvRow | (str csvStr, int rowIdx) | JSON object for data row rowIdx |
dedupCSV | (str csvStr, str colName) | CSV text with the first row kept per distinct column value |
readCSV returns raw file content, so readCSVRaw differs from the legacy readCSV (which returned objects); use parseCSV/parseToJson for objects.
Example
global setup(){ import("csv"); import("json"); }
global main(){
str data = "name,age\nalpha,30\nbeta,25\n";
println(global.csv.rowCount(data));
println(global.csv.getColumn(data, "name"));
println(global.csv.columnStats(data, "age"));
}
See also
- stdlib-contracts — the contract this module implements, including the error sentinel family it uses.
- builtins — the functions the interpreter implements itself.
- limitations — the full divergence register.