-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy path6-functional-pure.js
More file actions
82 lines (66 loc) · 2.06 KB
/
6-functional-pure.js
File metadata and controls
82 lines (66 loc) · 2.06 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict';
const fs = require('node:fs');
/* fp */
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x);
const curry = (fn) => (...args) => fn.bind(null, ...args);
const map = curry((fn, arr) => arr.map(fn));
const join = curry((str, arr) => arr.join(str));
const split = curry((splitOn, str) => str.split(splitOn));
const sort = curry((compareFn, arr) => arr.toSorted(compareFn));
const filter = curry((filterFn, arr) => arr.filter(filterFn));
/* utility */
const first = (arr) => arr[0];
const skipFirst = (arr) => arr.slice(1);
const hasValue = (val) => !!val;
const toStr = (val) => val.toString();
const appendCell = (row, value) => row.concat(value);
const cellPad = (index, str, width) => (
index ? str.padStart(width) : str.padEnd(width)
);
/* domain */
const cellWidth = (index) => [18, 10, 8, 8, 18, 6][index];
const renderCell = (cell, index) =>
cellPad(index, toStr(cell), cellWidth(index))
;
const renderRow = pipe(map(renderCell), join(''));
const renderTable = pipe(map(renderRow), join('\n'));
const getDensityCell = (row) => parseInt(row[3], 10);
const proportion = (max, val) => Math.round(parseInt(val, 10) * 100 / max);
const sortRowsByDensity = sort(
(row1, row2) => getDensityCell(row2) - getDensityCell(row1),
);
const calcMaxDensity = pipe(
sortRowsByDensity,
first,
getDensityCell,
);
const calcRowsProportionToMax = (rows) => (max) => rows.map(pipe(
getDensityCell,
(densityCell) => proportion(max, densityCell),
));
const appendProportionCell = (rows) => (proportions) => rows.map(
(row, index) => appendCell(row, proportions[index]),
);
const appendTableProportionCol = (rows) => pipe(
calcMaxDensity,
calcRowsProportionToMax(rows),
appendProportionCell(rows),
)(rows);
const parseTableLines = map(split(','));
const toLines = pipe(
split('\n'),
skipFirst,
filter(hasValue),
);
const readFile = (file) => fs.readFileSync(file, 'utf8');
const getDataset = pipe(
readFile,
toLines,
parseTableLines,
);
const main = pipe(
getDataset,
appendTableProportionCol,
renderTable,
);
console.log(main('./cities.csv'));