-
Notifications
You must be signed in to change notification settings - Fork 64
/
from-text-rows.js
61 lines (52 loc) · 1.62 KB
/
from-text-rows.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import ColumnTable from '../table/column-table';
import identity from '../util/identity';
import isFunction from '../util/is-function';
import repeat from '../util/repeat';
import valueParser from '../util/parse-values';
function defaultNames(n, off = 0) {
return repeat(n - off, i => `col${i + off + 1}`);
}
export default function(next, names, options) {
let row = next();
const n = row.length;
const automax = +options.autoMax || 1000;
const values = repeat(n, () => []);
names = names
? names.length < n ? [...names, defaultNames(n, names.length)] : names
: defaultNames(n);
// read in initial rows to guess types
let idx = 0;
for (; idx < automax && row; ++idx, row = next()) {
for (let i = 0; i < n; ++i) {
values[i].push(row[i] === '' ? null : row[i]);
}
}
// initialize parsers
const parsers = getParsers(names, values, options);
// apply parsers
parsers.forEach((parse, i) => {
if (parse === identity) return;
const v = values[i];
for (let r = 0; r < idx; ++r) {
if (v[r] != null) v[r] = parse(v[r]);
}
});
// parse remainder of file
for (; row; row = next()) {
for (let i = 0; i < n; ++i) {
values[i].push(row[i] ? parsers[i](row[i]) : null);
}
}
const columns = {};
names.forEach((name, i) => columns[name] = values[i]);
return new ColumnTable(columns, names);
}
function getParsers(names, values, options) {
const { parse = {} } = options;
const noParse = options.autoType === false;
return names.map(
(name, i) => isFunction(parse[name]) ? parse[name]
: noParse ? identity
: valueParser(values[i], options)
);
}