Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement https://github.com/mholt/PapaParse/issues/612 #898

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 14 additions & 2 deletions docs/docs.html
Expand Up @@ -510,8 +510,20 @@ <h5 id="config-details">Config Options</h5>
<code>transformHeader</code>
</td>
<td>
A function to apply on each header. Requires <code>header</code> to be <code>true</code>. The function receives the header as its first argument and the index as second.<br>
Only available starting with version 5.0.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should keep that this is only availalbe on the version 5.0

I also plan to do a minor version for the parameter. So the new parameter structure should be only available on 5.4+ versions. That should be noted too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved with ac6f191

A function to apply on each header. Requires <code>header</code> to be <code>true</code>. The function receives the header as its first argument and the index (the column number) as second. When used in conjunction with config.headerLines, the function receives a third and fourth parameter which are:
<ul>
<li><b>arr:</b> the string array of data for that row</li>
<li><b>acc:</b> the existing header for that column based on previous lines iteration ('' if no previous lines)</li>
<li><b>j:</b> the rowNumber (0 for the first line)</li>
</ul>
</td>
</tr>
<tr>
<td>
<code>headerLines</code>
</td>
<td>
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.
</td>
</tr>
<tr>
Expand Down
20 changes: 11 additions & 9 deletions papaparse.js
Expand Up @@ -1180,24 +1180,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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is bind required? Could we just ignore make the arguments at the end and optional?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bind is required because we're trying to parse a function into the .forEach() method, and unfortunately we have
"no-loop-func": "error"
and ecma5 versioning in our eslint config, which I think means no arrow functions. I assume this is for reasons of universalisable compatibility and speed. As a result, this is the only way to pass the loop iterator into the function.

}

function shouldApplyDynamicTyping(field) {
Expand Down