You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`ftcsv.parse` will load the entire csv file into memory, then parse it in one go, returning a lua table with the parsed data and a lua table containing the column headers. It has only two required parameters - a file name and delimiter (limited to one character). A few optional parameters can be passed in via a table (examples below).
20
+
### `ftcsv.parse(fileName, [, options])`
21
+
`ftcsv.parse` will load the entire csv file into memory, then parse it in one go, returning a lua table with the parsed data and a lua table containing the column headers. It has only one required parameter - the file name. A few optional parameters can be passed in via a table (examples below).
`ftcsv.parseLine` will open a file and read `options.bufferSize` bytes of the file. `bufferSize` defaults to 2^16 bytes (which provides the fastest parsing on most unix-based systems), or can be specified in the options. `ftcsv.parseLine` is an iterator and returns one line at a time. When all the lines in the buffer are read, it will read in another `bufferSize` bytes of a file and repeat the process until the entire file has been read.
31
31
32
32
If specifying `bufferSize` there are a couple of things to remember:
@@ -37,7 +37,7 @@ If specifying `bufferSize` there are a couple of things to remember:
37
37
Parsing through a csv file:
38
38
```lua
39
39
localftcsv=require("ftcsv")
40
-
forindex, zipcodeinftcsv.parseLine("free-zipcode-database.csv", ",") do
40
+
forindex, zipcodeinftcsv.parseLine("free-zipcode-database.csv") do
41
41
print(zipcode.Zipcode)
42
42
print(zipcode.State)
43
43
end
@@ -48,11 +48,18 @@ end
48
48
The options are the same for `parseLine` and `parse`, with the exception of `loadFromString` and `bufferSize`. `loadFromString` only works with `parse` and `bufferSize` can only be specified for `parseLine`.
49
49
50
50
The following are optional parameters passed in via the third argument as a table.
51
+
-`delimeter`
52
+
53
+
If your file doesn't use the comma character as the delimiter, you can specify your own. It is limited to one character and defaults to `,`
local actual = ftcsv.parse("a,b,c\r\napple,banana,carrot", ",", options)
73
+
local actual = ftcsv.parse("a,b,c\r\napple,banana,carrot", options)
67
74
```
68
75
69
76
-`fieldsToKeep`
@@ -74,7 +81,7 @@ The following are optional parameters passed in via the third argument as a tabl
74
81
75
82
```lua
76
83
local options = {loadFromString=true, fieldsToKeep={"a","f"}, rename={["c"] = "f"}}
77
-
local actual = ftcsv.parse("a,b,c\r\napple,banana,carrot\r\n", ",", options)
84
+
local actual = ftcsv.parse("a,b,c\r\napple,banana,carrot\r\n", options)
78
85
```
79
86
80
87
Also Note: If you apply a function to the headers via headerFunc, and want to select fields from fieldsToKeep, you need to have what the post-modified header would be in fieldsToKeep.
@@ -85,7 +92,7 @@ The following are optional parameters passed in via the third argument as a tabl
85
92
86
93
```lua
87
94
local options = {loadFromString=true, ignoreQuotes=true}
88
-
local actual = ftcsv.parse('a,b,c\n"apple,banana,carrot', ",", options)
95
+
local actual = ftcsv.parse('a,b,c\n"apple,banana,carrot', options)
89
96
```
90
97
91
98
-`headerFunc`
@@ -95,23 +102,23 @@ The following are optional parameters passed in via the third argument as a tabl
95
102
Ex: making all fields uppercase
96
103
```lua
97
104
local options = {loadFromString=true, headerFunc=string.upper}
98
-
local actual = ftcsv.parse("a,b,c\napple,banana,carrot", ",", options)
105
+
local actual = ftcsv.parse("a,b,c\napple,banana,carrot", options)
99
106
```
100
107
101
108
-`headers`
102
109
103
110
Set `headers` to `false` if the file you are reading doesn't have any headers. This will cause ftcsv to create indexed tables rather than a key-value tables for the output.
104
111
105
112
```lua
106
-
local options = {loadFromString=true, headers=false}
107
-
local actual = ftcsv.parse("apple>banana>carrot\ndiamond>emerald>pearl", ">", options)
113
+
local options = {loadFromString=true, headers=false, delimiter=">"}
114
+
local actual = ftcsv.parse("apple>banana>carrot\ndiamond>emerald>pearl", options)
108
115
```
109
116
110
117
Note: Header-less files can still use the `rename` option and after a field has been renamed, it can specified as a field to keep. The `rename` syntax changes a little bit:
111
118
112
119
```lua
113
-
local options = {loadFromString=true, headers=false, rename={"a","b","c"}, fieldsToKeep={"a","b"}}
114
-
local actual = ftcsv.parse("apple>banana>carrot\ndiamond>emerald>pearl", ">", options)
120
+
local options = {loadFromString=true, headers=false, rename={"a","b","c"}, fieldsToKeep={"a","b"}, delimiter=">"}
121
+
local actual = ftcsv.parse("apple>banana>carrot\ndiamond>emerald>pearl", options)
115
122
```
116
123
117
124
In the above example, the first field becomes 'a', the second field becomes 'b' and so on.
@@ -120,7 +127,7 @@ For all tested examples, take a look in /spec/feature_spec.lua
120
127
121
128
The options can be string together. For example if you wanted to `loadFromString` and not use `headers`, you could use the following:
if `fieldsToKeep` is set in the encode process, only the fields specified will be written out to a file.
147
+
if `fieldsToKeep` is set in the encode process, only the fields specified will be written out to a file. The `fieldsToKeep` will be written out in the order that is specified.
141
148
142
149
```lua
143
150
local output = ftcsv.encode(everyUser, ",", {fieldsToKeep={"Name", "Phone", "City"}})
@@ -148,7 +155,7 @@ file:close()
148
155
if `onlyRequiredQuotes` is set to `true`, the output will only include quotes around fields that are quotes, have newlines, or contain the delimter.
@@ -184,7 +191,7 @@ NOTE: times are measured using `os.clock()`, so they are in CPU seconds. Each te
184
191
Benchmarkswererununderftcsv1.2.0
185
192
186
193
##Performance
187
-
Ididsomebasictestingandfoundthatinlua, ifyouwanttoiterateoverastringcharacter-by-characterandcomparechars, `string.byte` performsfasterthan`string.sub`. Assuch, ftcsviteratesoverthewholefileanddoesbytecomparestofindquotesanddelimitersandthengeneratesatablefromit. Whenusingvanillalua, itprovedfastertouse`string.find` insteadofiteratingcharacterbycharacter (whichisfasterinLuaJIT), softcsvaccountsforthatandwillperformthefastestoptionthatisavailble. Ifyouhavethoughtsonhowtoimproveperformance (eitherbigpictureorspecificallywithinthecode), createaGitHubissue-I'd love to hear about it!
194
+
Ididsomebasictestingandfoundthatinlua, ifyouwanttoiterateoverastringcharacter-by-characterandcomparechars, `string.byte` performsfasterthan`string.sub`. Assuch, ftcsviteratesoverthewholefileanddoesbytecomparestofindquotesanddelimitersandthengeneratesatablefromit. Whenusingvanillalua, itprovedfastertouse`string.find` insteadofiteratingcharacterbycharacter (whichisfasterinLuaJIT), softcsvaccountsforthatandwillperformthefastestoptionthatisavailable. Ifyouhavethoughtsonhowtoimproveperformance (eitherbigpictureorspecificallywithinthecode), createaGitHubissue-I'd love to hear about it!
188
195
189
196
190
197
##Contributing
@@ -200,6 +207,16 @@ Feel free to create a new issue for any bugs you've found or help you need. If y
200
207
8.Enjoythechangesmade!
201
208
202
209
210
+
##Delimiternolongerrequiredasof1.4.0!
211
+
Startingwithversion1.4.0, thedelimiternolongerrequiredasthesecondargument. **Butdon't worry,** ftcsv remains backwards compatible! We check the argument types and adjust parsing as necessary. There is no intention to remove this backwards compatibility layer, so you can always enjoy your up-to-date lightning fast CSV parser!
assert(#delimiter==1andtype(delimiter) =="string", "the delimiter must be of string type and exactly one character")
@@ -404,50 +420,54 @@ local function parseOptions(delimiter, options, fromParseLine)
404
420
405
421
ifoptionsthen
406
422
407
-
ifoptions.headers~=nilthen
408
-
assert(type(options.headers) =="boolean", "ftcsv only takes the boolean 'true' or 'false' for the optional parameter 'headers' (default 'true'). You passed in '" ..tostring(options.headers) .."' of type '" ..type(options.headers) .."'.")
409
-
end
423
+
ifoptions.headers~=nilthen
424
+
assert(type(options.headers) =="boolean", "ftcsv only takes the boolean 'true' or 'false' for the optional parameter 'headers' (default 'true'). You passed in '" ..tostring(options.headers) .."' of type '" ..type(options.headers) .."'.")
425
+
end
410
426
411
-
ifoptions.rename~=nilthen
412
-
assert(type(options.rename) =="table", "ftcsv only takes in a key-value table for the optional parameter 'rename'. You passed in '" ..tostring(options.rename) .."' of type '" ..type(options.rename) .."'.")
413
-
end
427
+
ifoptions.rename~=nilthen
428
+
assert(type(options.rename) =="table", "ftcsv only takes in a key-value table for the optional parameter 'rename'. You passed in '" ..tostring(options.rename) .."' of type '" ..type(options.rename) .."'.")
429
+
end
414
430
415
-
ifoptions.fieldsToKeep~=nilthen
416
-
assert(type(options.fieldsToKeep) =="table", "ftcsv only takes in a list (as a table) for the optional parameter 'fieldsToKeep'. You passed in '" ..tostring(options.fieldsToKeep) .."' of type '" ..type(options.fieldsToKeep) .."'.")
error("ftcsv: fieldsToKeep only works with header-less files when using the 'rename' functionality")
431
+
ifoptions.fieldsToKeep~=nilthen
432
+
assert(type(options.fieldsToKeep) =="table", "ftcsv only takes in a list (as a table) for the optional parameter 'fieldsToKeep'. You passed in '" ..tostring(options.fieldsToKeep) .."' of type '" ..type(options.fieldsToKeep) .."'.")
433
+
localofieldsToKeep=options.fieldsToKeep
434
+
ifofieldsToKeep~=nilthen
435
+
fieldsToKeep= {}
436
+
forj=1, #ofieldsToKeepdo
437
+
fieldsToKeep[ofieldsToKeep[j]] =true
426
438
end
427
439
end
428
-
429
-
ifoptions.loadFromString~=nilthen
430
-
assert(type(options.loadFromString) =="boolean", "ftcsv only takes a boolean value for optional parameter 'loadFromString'. You passed in '" ..tostring(options.loadFromString) .."' of type '" ..type(options.loadFromString) .."'.")
error("ftcsv: fieldsToKeep only works with header-less files when using the 'rename' functionality")
431
442
end
443
+
end
432
444
433
-
ifoptions.headerFunc~=nilthen
434
-
assert(type(options.headerFunc) =="function", "ftcsv only takes a function value for optional parameter 'headerFunc'. You passed in '" ..tostring(options.headerFunc) .."' of type '" ..type(options.headerFunc) .."'.")
435
-
end
445
+
ifoptions.loadFromString~=nilthen
446
+
assert(type(options.loadFromString) =="boolean", "ftcsv only takes a boolean value for optional parameter 'loadFromString'. You passed in '" ..tostring(options.loadFromString) .."' of type '" ..type(options.loadFromString) .."'.")
447
+
end
448
+
449
+
ifoptions.headerFunc~=nilthen
450
+
assert(type(options.headerFunc) =="function", "ftcsv only takes a function value for optional parameter 'headerFunc'. You passed in '" ..tostring(options.headerFunc) .."' of type '" ..type(options.headerFunc) .."'.")
451
+
end
452
+
453
+
ifoptions.ignoreQuotes==nilthen
454
+
options.ignoreQuotes=false
455
+
else
456
+
assert(type(options.ignoreQuotes) =="boolean", "ftcsv only takes a boolean value for optional parameter 'ignoreQuotes'. You passed in '" ..tostring(options.ignoreQuotes) .."' of type '" ..type(options.ignoreQuotes) .."'.")
457
+
end
436
458
437
-
ifoptions.ignoreQuotes==nilthen
438
-
options.ignoreQuotes=false
459
+
iffromParseLine==truethen
460
+
ifoptions.bufferSize==nilthen
461
+
options.bufferSize=2^16
439
462
else
440
-
assert(type(options.ignoreQuotes) =="boolean", "ftcsv only takes a boolean value for optional parameter 'ignoreQuotes'. You passed in '" ..tostring(options.ignoreQuotes) .."' of type '" ..type(options.ignoreQuotes) .."'.")
463
+
assert(type(options.bufferSize) =="number", "ftcsv only takes a number value for optional parameter 'bufferSize'. You passed in '" ..tostring(options.bufferSize) .."' of type '" ..type(options.bufferSize) .."'.")
441
464
end
442
465
443
-
ifoptions.bufferSize==nilthen
444
-
options.bufferSize=2^16
445
-
else
446
-
assert(type(options.bufferSize) =="number", "ftcsv only takes a number value for optional parameter 'bufferSize'. You passed in '" ..tostring(options.bufferSize) .."' of type '" ..type(options.bufferSize) .."'.")
447
-
iffromParseLine==falsethen
448
-
error("ftcsv: bufferSize can only be specified using 'parseLine'. When using 'parse', the entire file is read into memory")
449
-
end
466
+
else
467
+
ifoptions.bufferSize~=nilthen
468
+
error("ftcsv: bufferSize can only be specified using 'parseLine'. When using 'parse', the entire file is read into memory")
0 commit comments