Repository: mholt/PapaParse (JavaScript)

Issue:
'columns' unparse config not working when first object doesn't have all properties
When using the `columns` unparse config option together with a data array where the first object does not have all properties that are listed in the `columns` array, then not all columns of the `columns` array are used even if later objects have these values.

E.g.
```javascript
const columns= ["First", "Second", "Third"];
const rows= [
  { First: "1-1"},
  {
    First: "2-1",
    Second: "2-2",
    "Third": "2-3",
  },
];
const result = Papa.unparse(
  { data: rows},
  {
    header: true,
    columns: columns,
  }
);
console.log(result)
```
The `result` is 
```
First
1-1
2-1
```

instead of the expected

```
First,Second,Third
1-1,,
2-1,2-2,2-3
```


Discussion:
I guess the problem is that the columns array is modified on the first colum when it should not be. 
Could you please upload a PR to fix it which includes a minimum test case (your example sounds like a good solution)
Thanks for the quick response. I will try to make the PR. As this would be my first contribution to Papaparse, do you @pokoli have some pointers for me where I would have to look for a solution/implement the tests and the code?
@TheSlimvReal That will be great. 
THinks to note: 

* You do not need to update the minified file as this will be done by the release process.
* There are already tests for unparse, make sure to add yours at the end (feel free to use them as reference).
* Feel free to ask any other doubts you may have ;-) 
After going through the tests cases I found this one:
```javascript
{
  description: "Column option used to manually specify keys",
  notes: "...",
  input: [{a: 1, b: '2'}, {}, {a: 3, d: 'd', c: 4,}],
  config: {columns: ['a', 'b', 'c']},
  expected: 'a,b,c\r\n1,2,\r\n\r\n3,,4'
},
```
Which made me realize that with 
```javascript
...
const result = Papa.unparse(
  rows,   // <-- pass the data object directly instead of { data: rows }
  {
    header: true,
    columns: columns,
  }
);
...
```
My above example works. 

Therefore my question @pokoli: Is it a bug that it does not work when passing an object instead of an array or is this behavior intended?
anyway I created a PR that resolves the issue #919 
Generally, I am wondering whether the options `columns` and `fields` are not the same thing and `columns` could therefore be removed?



Patch:
diff --git a/papaparse.js b/papaparse.js
index df7ba066..667a109f 100755
--- a/papaparse.js
+++ b/papaparse.js
@@ -307,7 +307,7 @@ License: MIT
 			if (Array.isArray(_input.data))
 			{
 				if (!_input.fields)
-					_input.fields =  _input.meta && _input.meta.fields;
+					_input.fields = _input.meta && _input.meta.fields || _columns;
 
 				if (!_input.fields)
 					_input.fields =  Array.isArray(_input.data[0])


Test patch:
diff --git a/tests/test-cases.js b/tests/test-cases.js
index ab806ba3..469c74cc 100644
--- a/tests/test-cases.js
+++ b/tests/test-cases.js
@@ -1865,6 +1865,13 @@ var UNPARSE_TESTS = [
 		config: {columns: ['a', 'b', 'c']},
 		expected: 'a,b,c\r\n1,2,\r\n\r\n3,,4'
 	},
+	{
+		description: "Column option used to manually specify keys with input type object",
+		notes: "Should not throw any error when attempting to serialize key not present in object. Columns are different than keys of the first object. When an object is missing a key then the serialized value should be an empty string.",
+		input: { data: [{a: 1, b: '2'}, {}, {a: 3, d: 'd', c: 4,}] },
+		config: {columns: ['a', 'b', 'c']},
+		expected: 'a,b,c\r\n1,2,\r\n\r\n3,,4'
+	},
 	{
 		description: "Use different escapeChar",
 		input: [{a: 'foo', b: '"quoted"'}],