Last active
February 4, 2021 02:58
-
-
Save gustawdaniel/afb5a804556c6e90419a438bb0b37359 to your computer and use it in GitHub Desktop.
process_nbp_chf_1984_2020.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fs from 'fs' | |
interface YearData { | |
[key: string]: { | |
col: number, | |
div: number, | |
values: { [key: string]: number }[] | |
} | |
} | |
interface OutData { | |
[key: string]: { | |
[key: string]: number | |
} | |
} | |
const FILES_FILTER = (e: string, i: number) => i <= Infinity | |
const ROWS_FILTER = (e: string, i: number) => i <= Infinity | |
const DROP_SPACES = (l: string): string => l.replace(/\s+/g, '') | |
const DROP_JUNK_LINES = (l: string): string => l.replace(/(Nr)|(data)|(WALUTA\/CURRENCY)|(\.tab)/ig, '') | |
const DROP_EMPTY_LINES = (e:string) => !/^,*$/.test(e) | |
const dict: { [key: string]: string } = { | |
'W.Brytania': 'CHF' | |
} | |
const decomposeBaseSettingsFromNames = (localArr: string[]) => localArr.reduce((p: YearData, n: string, i: number): YearData => { | |
if (Object.keys(dict).includes(n)) { | |
p[dict[n]] = { col: i, div: 1, values: [] } | |
} | |
return p | |
}, {}) | |
const decomposeBaseSettingsFromCodes = (localArr: string[]) => localArr.reduce((p: YearData, n: string, i: number): YearData => { | |
const [, div, curr] = n.match(/^(\d+)(\w+)$/) || [] | |
if (parseInt(div) && curr && Object.values(dict).includes(curr)) { | |
p[curr] = { col: i, div: parseInt(div), values: [] } | |
} | |
return p | |
}, {}) | |
const getDate = (input: string) => { | |
if (/^\d{2}\.\d{2}\.\d{4}/.test(input)) { | |
return input.split('.').reverse().join('-') | |
} | |
if (/^\d{2}\/\d{2}\/\d{4}/.test(input)) { | |
const [m, d, y] = input.split('/') | |
return [y, m, d].join('-') | |
} | |
return false | |
} | |
const getDateFromArr = (arr: string[]) => { | |
return getDate(arr[0]) || getDate(arr[1]) | |
} | |
const mergeYears = (payload: YearData[]): OutData => { | |
return payload.reduce((p: OutData, n: YearData) => { | |
Object.keys(n).forEach(key => { | |
if (p.hasOwnProperty(key)) { | |
p[key] = {...p[key], ...n[key].values.reduce((p,n) => ({...p,...n}))} | |
} else { | |
p[key] = n[key].values.reduce((p,n) => ({...p,...n})) | |
} | |
}) | |
return p | |
}, {}) | |
} | |
const main = () => { | |
const rawDir = process.cwd() + `/raw` | |
return mergeYears(fs.readdirSync(rawDir).filter(f => f.endsWith('csv')) | |
.filter(FILES_FILTER) | |
.map((name, i) => { | |
const arr = fs | |
.readFileSync(`${rawDir}/${name}`) | |
.toString() | |
.split(`\n`) | |
.map(DROP_SPACES) | |
.map(DROP_JUNK_LINES) | |
.filter(DROP_EMPTY_LINES) | |
.filter(ROWS_FILTER) | |
.map(l => l.split(',').map(DROP_SPACES)) | |
const head = arr.shift() | |
if (!head) throw Error('File do not have header line.') | |
let settings: YearData = decomposeBaseSettingsFromNames(head) | |
if (Object.keys(settings).length) { | |
const subHead = arr.shift() | |
if (!subHead) throw Error('File do not have sub-header line.') | |
Object.keys(settings).forEach(key => { | |
settings[key].div = parseInt(subHead[settings[key].col]) | |
}) | |
} else { | |
settings = decomposeBaseSettingsFromCodes(head) | |
} | |
arr.forEach(localArr => { | |
const date = getDateFromArr(localArr) | |
if (typeof date === 'string') { | |
Object.keys(settings).forEach(key => { | |
settings[key].values.push({ [date]: parseFloat(localArr[settings[key].col]) / settings[key].div }) | |
}) | |
} | |
}) | |
return settings | |
})) | |
} | |
fs.writeFileSync(process.cwd() + '/chf.json', JSON.stringify(main())) | |
console.dir(main(), {depth: Infinity, maxArrayLength: Infinity}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment