From 7225d8ec79b121f477331afcf0cc05699889ad47 Mon Sep 17 00:00:00 2001 From: marshall007 Date: Fri, 8 Jul 2016 19:17:31 -0500 Subject: [PATCH] Support dynamic typing on explicitly defined columns --- papaparse.js | 49 +++++++++++++++++++++++++++------------------ tests/test-cases.js | 32 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/papaparse.js b/papaparse.js index 0537e0c..4dd12bb 100644 --- a/papaparse.js +++ b/papaparse.js @@ -179,6 +179,7 @@ function CsvToJson(_input, _config) { _config = _config || {}; + _config.dynamicTyping = _config.dynamicTyping || false; if (_config.worker && Papa.WORKERS_SUPPORTED) { @@ -845,6 +846,20 @@ _results.data.splice(0, 1); } + function parseDynamic(field, value) + { + if ((_config.dynamicTyping[field] || _config.dynamicTyping) === true) + { + if (value === 'true' || value === 'TRUE') + return true; + else if (value === 'false' || value === 'FALSE') + return false; + else + return tryParseFloat(value); + } + return value; + } + function applyHeaderAndDynamicTyping() { if (!_results || (!_config.header && !_config.dynamicTyping)) @@ -852,37 +867,31 @@ for (var i = 0; i < _results.data.length; i++) { - var row = {}; + var row = _config.header ? {} : []; for (var j = 0; j < _results.data[i].length; j++) { - if (_config.dynamicTyping) - { - var value = _results.data[i][j]; - if (value === 'true' || value === 'TRUE') - _results.data[i][j] = true; - else if (value === 'false' || value === 'FALSE') - _results.data[i][j] = false; - else - _results.data[i][j] = tryParseFloat(value); - } + var field = j; + var value = _results.data[i][j]; if (_config.header) + field = j >= _fields.length ? '__parsed_extra' : _fields[j]; + + value = parseDynamic(field, value); + + if (field === '__parsed_extra') { - if (j >= _fields.length) - { - if (!row['__parsed_extra']) - row['__parsed_extra'] = []; - row['__parsed_extra'].push(_results.data[i][j]); - } - else - row[_fields[j]] = _results.data[i][j]; + row[field] = row[field] || []; + row[field].push(value); } + else + row[field] = value; } + _results.data[i] = row; + if (_config.header) { - _results.data[i] = row; if (j > _fields.length) addError('FieldMismatch', 'TooManyFields', 'Too many fields: expected ' + _fields.length + ' fields but parsed ' + j, i); else if (j < _fields.length) diff --git a/tests/test-cases.js b/tests/test-cases.js index 4f98590..9dda6ff 100644 --- a/tests/test-cases.js +++ b/tests/test-cases.js @@ -652,6 +652,38 @@ var PARSE_TESTS = [ errors: [] } }, + { + description: "Dynamic typing applies to specific columns", + input: 'A,B,C\r\n1,2.2,1e3\r\n-4,-4.5,-4e-5', + config: { header: true, dynamicTyping: { A: true, C: true } }, + expected: { + data: [{"A": 1, "B": "2.2", "C": 1000}, {"A": -4, "B": "-4.5", "C": -0.00004}], + errors: [] + } + }, + { + description: "Dynamic typing applies to specific columns by index", + input: '1,2.2,1e3\r\n-4,-4.5,-4e-5\r\n-,5a,5-2', + config: { dynamicTyping: { 1: true } }, + expected: { + data: [["1", 2.2, "1e3"], ["-4", -4.5, "-4e-5"], ["-", "5a", "5-2"]], + errors: [] + } + }, + { + description: "Dynamic typing can be applied to `__parsed_extra`", + input: 'A,B,C\r\n1,2.2,1e3,5.5\r\n-4,-4.5,-4e-5', + config: { header: true, dynamicTyping: { A: true, C: true, __parsed_extra: true } }, + expected: { + data: [{"A": 1, "B": "2.2", "C": 1000, "__parsed_extra": [ 5.5 ]}, {"A": -4, "B": "-4.5", "C": -0.00004}], + errors: [{ + "type": "FieldMismatch", + "code": "TooManyFields", + "message": "Too many fields: expected 3 fields but parsed 4", + "row": 0 + }] + } + }, { description: "Blank line at beginning", input: '\r\na,b,c\r\nd,e,f',