diff --git a/.gitignore b/.gitignore index e412004..af8740f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /out /node_modules -notes \ No newline at end of file +notes +.vscode \ No newline at end of file diff --git a/README.md b/README.md index ab9f6ce..479dd71 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # census-csv-parser -_v 1.0.4_ +_v 1.0.5_ [https://github.com/klm127/census-csv-parser](https://github.com/klm127/census-csv-parser) diff --git a/changelog.md b/changelog.md index 09b3c4c..fc1af85 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,6 @@ +2021/07/25 - v 1.0.5 - + + Added mergeToHeader function to Parser. This takes a row or column (depending on how you set your headers) and merges into the header column as an array, allowing for the nesting of data. 2021/07/14 - v 1.0.4 - diff --git a/package.json b/package.json index 542103c..8b88bf4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "census-csv-parser", - "version": "1.0.4", + "version": "1.0.5", "description": "tool for parsing census csvs into .json objects", "homepage": "https://quaffingcode.com", "main": "parser.js", diff --git a/parser.js b/parser.js index 62e1171..c20b8d6 100644 --- a/parser.js +++ b/parser.js @@ -132,6 +132,43 @@ class Parser { this.columnHeaders = propArr; } } + /** + * Merges another row or column into the header column so that header column becomes an array, which causes the higher indexed elements of the array to nest inside the lower indexed elements of the array in the final output json object. + * + * @param {number} index The index to merge to the header(not counting the header itself in the index). If headers set to row, merges that index row. If set to col, merges that column + */ + mergeToHeader(index) { + if(this.propArr == 'COL') { + let mergeRow = this.data[index]; + for(let i = 0; i < mergeRow.length; i++) { + let header = this.columnHeaders[i]; + let appendValue = mergeRow[i]; + if(header instanceof Array) { + header.push(appendValue); + } + else { + this.columnHeaders[i] = [header, appendValue]; + } + } + this.data.splice(index,1) + this.rowHeaders.splice(index,1) + } + else { + for(let i = 0; i < this.data.length; i++) { + let mergeValue = this.data[i][index]; + let previousHeader = this.rowHeaders[i]; + if(previousHeader instanceof Array) { + previousHeader.push(mergeValue); + } + else { + this.rowHeaders[i] = [previousHeader, mergeValue]; + } + this.data[i].splice(index,1); + } + this.columnHeaders.splice(index,1); + + } + } /** * Maps data to an object. The object will contain a property for each value not in the selected props array. For each array in the selected props array, a chain of sub-properties will be created. Metadata, if extant, will be added as properties to the mother object. * So if you have this data: diff --git a/tests/testparser.js b/tests/testparser.js index 428b65a..69cc7bc 100644 --- a/tests/testparser.js +++ b/tests/testparser.js @@ -214,6 +214,58 @@ try { }, 'Chopping rows with header column worked as expected') log('Chopping rows on header regex worked as expected','green') + // test merging a column into the row headers as an array for nesting + testArray = [ + ["County","Industry","Number of Firms","Number of Employees"], + ["Mercer","Automobile Manufacturing", 3, 112], + ["Mercer","Wood Product Manufacturing", 12, 195], + ["Dodd","Food Service", 50, 220], + ["Dodd","Automobile Manufacturing", 1, 10] + ]; + parser = new Parser(testArray); + parser.setHeaders(0,0) + parser.setProps('ROW'); + parser.mergeToHeader(0); + let out = parser.mapProps(); + assert.deepStrictEqual(out, { + overlapHeader: 'County', + 'Number of Firms': { + Mercer: { 'Automobile Manufacturing': 3, 'Wood Product Manufacturing': 12 }, + Dodd: { 'Food Service': 50, 'Automobile Manufacturing': 1 } + }, + 'Number of Employees': { + Mercer: { + 'Automobile Manufacturing': 112, + 'Wood Product Manufacturing': 195 + }, + Dodd: { 'Food Service': 220, 'Automobile Manufacturing': 10 } + } + },'Merging a col for array-style mapping did not work as expected'); + log('Merging a column into the row headers worked as expected','green') + + testArray = [ + ["County","Franklin","Preston","Franklin","Preston","Preston"], + ["Industry","Financial Services","Financial Services","Auto Repair","Auto Repair","Consulting"], + ["Tax Revenue (mil)",3,8,0.4,0.3,2], + ["Employees", 900, 1950, 320, 640, 50] + ] + parser = new Parser(testArray); + parser.setHeaders(0,0); + parser.setProps('COL'); + parser.mergeToHeader(0); + out = parser.mapProps(); + assert.deepStrictEqual(out, { + overlapHeader: 'County', + 'Tax Revenue (mil)': { + Franklin: { 'Financial Services': 3, 'Auto Repair': 0.4 }, + Preston: { 'Financial Services': 8, 'Auto Repair': 0.3, Consulting: 2 } + }, + Employees: { + Franklin: { 'Financial Services': 900, 'Auto Repair': 320 }, + Preston: { 'Financial Services': 1950, 'Auto Repair': 640, Consulting: 50 } + } + }, 'Merging a row for array-style mapping did not work as expected'); + log('Merging a row into the column headers worked as expected','green')