diff --git a/docs/docs.html b/docs/docs.html
index cf198a5..7a2b1c9 100644
--- a/docs/docs.html
+++ b/docs/docs.html
@@ -510,8 +510,25 @@ var csv = Papa.unparse({
transformHeader
- A function to apply on each header. Requires header to be true . The function receives the header as its first argument and the index as second.
+ A function to apply on each header. Requires header to be true . The arguments are:
+
+ - header: the current header text, as parsed from the appropriate cell in the specified header row
+ - index: the column number of the header text (0 for first column)
+ - arr: the string array of data for that row
+ - acc: the existing header for that column based on previous lines iteration ('' if no previous lines)
+ - j: the rowNumber (0 for the first line)
+
Only available starting with version 5.0.
+ The latter three parameters (arr, acc, j) are only available when used in conjunction with config.headerLines and from version 5.4+.
+ |
+
+
+
+ headerLines
+ |
+
+ The number of rows which will be used to transform into a header, and removed from the rest of the data. Requires header to be true. Default 1.
+ Only available starting with veresion 5.4.
|
diff --git a/papaparse.js b/papaparse.js
index 1b9ea51..732f432 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -1184,24 +1184,26 @@ License: MIT
if (!_results)
return;
- function addHeader(header, i)
+ var headerLines = _config.headerLines || 1;
+ function addHeader(j, header, i, arr)
{
if (isFunction(_config.transformHeader))
- header = _config.transformHeader(header, i);
+ header = _config.transformHeader(header, i, arr, _fields[i] || '', j);
- _fields.push(header);
+ _fields[i] = header;
}
-
if (Array.isArray(_results.data[0]))
{
- for (var i = 0; needsHeaderRow() && i < _results.data.length; i++)
- _results.data[i].forEach(addHeader);
-
- _results.data.splice(0, 1);
+ for (var j = 0; j < Math.min(headerLines, _results.data.length); j++)
+ {
+ // A function which takes two arguments (header, i) where j is set by the fact it is called in this loop. It then calls addHeader() with all three arguments
+ _results.data[j].forEach(addHeader.bind(null, j));
+ }
+ _results.data.splice(0, headerLines);
}
// if _results.data[0] is not an array, we are in a step where _results.data is the row.
else
- _results.data.forEach(addHeader);
+ _results.data.forEach(addHeader.bind(null, 0));
}
function shouldApplyDynamicTyping(field) {
diff --git a/tests/test-cases.js b/tests/test-cases.js
index 1b0ee33..49beb85 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -767,6 +767,15 @@ var PARSE_TESTS = [
errors: []
}
},
+ {
+ description: "Header row is generated from multiple rows when transformheader function is provided and config.headerLines is set",
+ input: "A,B,C\r\nD,E,F\r\nG,H,I\r\nadg,beh,cfi",
+ config: { header: true, transformHeader: function(header, i, arr, acc, j) { return acc + (j % 2 ? header.toLowerCase() : header); }, headerLines: 3 },
+ expected: {
+ data: [{"AdG": "adg", "BeH": "beh", "CfI": "cfi"}],
+ errors: []
+ }
+ },
{
description: "transformHeader accepts and optional index attribute",
input: 'A,B,C\r\na,b,c',