I'm hoping someone can show me a less verbose and more efficient way to achieve the following:
I have some JSON data (via PapaParse) which contains an array of objects. It looks something like this:
const myJSON = [
{subscriber_id: "1", segment: "something", status: "subscribed", created_at: "2019-01-16 05:55:20"},
{subscriber_id: "1", segment: "another thing", status: "subscribed", created_at: "2019-04-02 23:06:54"},
{subscriber_id: "1", segment: "something else", status: "subscribed", created_at: "2019-04-03 03:55:16"},
];
My goal is to iterate through the data and merge all objects with the same value for subscriber_id into a single object with all the segment values combined into an array, so that the result will look like this:
[
{subscriber_id: "1", segment: ["something", "another thing", "something else"], status: "subscribed", created_at: "2019-01-16 05:55:20"}
];
Below is my current code, which works. But I'm interested in ways to improve it.
Note: In my actual project, I allow the user to choose which column is used to identify duplicate rows and which columns to combine, which is why my mergeCSV function takes 3 parameters.
const myJSON = [{
subscriber_id: "1",
segment: "something",
status: "subscribed",
created_at: "2019-01-16 05:55:20"
},
{
subscriber_id: "1",
segment: "another thing",
status: "subscribed",
created_at: "2019-04-02 23:06:54"
},
{
subscriber_id: "1",
segment: "something else",
status: "subscribed",
created_at: "2019-04-03 03:55:16"
},
],
myKey = "subscriber_id",
myColumns = ["segment"];
const mergeCSV = (theData, theKey, theColumns) => {
const l = theData.length;
let theOutput = [];
// add the first row
theOutput.push(theData[0]);
// convert columns to be combined into arrays
theColumns.forEach(col => theOutput[0][col] = [theOutput[0][col]]);
// loop through the main file from beginning to end
for (var a = 1; a < l; a++) {
// reset duplicate flag
let duplicate = false;
// loop through theOutput file from end to beginning
for (var b = theOutput.length; b > 0; b--) {
const n = b - 1;
// for each of the columns which will be combined
for (var i = 0; i < theColumns.length; i++) {
// if theKey matches
if (theData[a][theKey] === theOutput[n][theKey]) {
duplicate = true;
// add the column data to existing output row
theOutput[n][theColumns[i]].push(theData[a][theColumns[i]]);
break;
}
}
}
// if theKey doesn't match any rows in theOutput
if (!duplicate) {
// add the row
theOutput.push(theData[a]);
// convert columns to be combined into arrays
theColumns.forEach(col => theOutput[theOutput.length - 1][col] = [theOutput[theOutput.length - 1][col]]);
}
}
return theOutput;
}
console.log( mergeCSV(myJSON, myKey, myColumns) );