I want to convert JSON responses to CSV format. I was able to figure out how to properly generate the headers in a way where parents of a key are appended together to generate a proper header. The problem I have is structuring the data that corresponds to each row. For example lets say I have these columns called id, tags, and friends_id. Taking the case for id = 1, tags = [car, plane] friends_id = [0,1,2]. It should kind of look like this in a csv table format.
+-------+-------+------------+
| id    | tags  | friends_id |
+-------+-------+------------+
| 1     | car   | 0          |
+-------+-------+------------+
| empty | plane | 1          |
+-------+-------+------------+
| empty | empty | 2          |
+-------+-------+------------+
| 2     | ...   | ...        |
+-------+-------+------------+
Here's some test data that I'm working on.
{
    "_id": "5cfe7d3c6deeeef08ce0444b",
    "name": "Debra Milligain",
    "phone": "+1 (906) 432-2182",
    "address": "676 Merit Court, Steinhatchee, Oregon, 5491",
    "tags": [
        "consequat",
        "reprehenderit",
        "amet"
    ],
    "Work": {
        "skills": [{
                "id": 0,
                "name": "Programming"
            },
            {
                "id": 1,
                "name": "Business"
            }
        ]
    },
    "friends": [{
            "id": 0,
            "name": "Stafford Hernandez"
        },
        {
            "id": 1,
            "name": "Colleen Christensen"
        },
        {
            "id": 2,
            "name": "Barker Keith"
        }
    ],
    "greeting": [],
    "favoriteFruit": "banana"
}
The following code (Which is a solution to an earlier problem I had, found here is what I use to recursively generate headers into a map or hash table and append their corresponding values.
var arrayOfHeaders = {};
var headerDirectory = "";
var rootLevel = true;
var temp = ""
var firstWalkthrough = true;
function traverseJSON(obj){
    for (var o in obj) {
        if (typeof obj[o] == "object") {
            //console.log("Before traversal ", o)
            //console.log("Traversing the object: ", obj[o])
            if(!isNaN(o)){
                //console.log("Current position is a number ", o)
            }else{
                console.log("Adding to directory... " , o)
                headerDirectory += (headerDirectory == "") ? o : "_" + o;
            }
            rootLevel = false;
            if (firstWalkthrough){
                firstWalkthrough = false;
                //if (o == 0) 
                rootLevel = true;
            }
            traverseJSON(obj[o]);
            rootLevel = true;
            temp = headerDirectory;
            headerDirectory = "";
        } else {
            if (rootLevel) {
                if(isNaN(o)){ 
                    headerDirectory = "";
                    //console.log("Has value and is root ", o, "and temp ", temp)
                    arrayOfHeaders[o] +=  ",\"" + obj[o] + "\"";
                }else{
                    arrayOfHeaders[headerDirectory+"_"+o] +=  ",\"" + obj[o] + "\"";
                }
            }
            else {
                //console.log("Has value and is not root ", o)
                //console.log("Current Header Directory " + headerDirectory)
                //console.log("Saved temp : ", temp)
                if(isNaN(o)){ 
                    if(headerDirectory == "") headerDirectory = temp; 
                    //arrayOfHeaders.push(headerDirectory + "_" + o)
                    arrayOfHeaders[headerDirectory + "_" + o] += ",\"" + obj[o] + "\"";
                }              
            }
        }
    }
    // console.log("Array of Headers : ", arrayOfHeaders)
}
This is the actual response from arrayofHeaders:
{ _id: 'undefined,"5cfe7d3c6deeeef08ce0444b"',
  name: 'undefined,"Debra Milligain"',
  phone: 'undefined,"+1 (906) 432-2182"',
  address: 'undefined,"676 Merit Court, Steinhatchee, Oregon, 5491"',
  tags_0: 'undefined,"consequat"',
  tags_1: 'undefined,"reprehenderit"',
  tags_2: 'undefined,"amet"',
  'Work_skills_id-skill': 'undefined,"0","Business"',
  'Work_skills_name-skill': 'undefined,"Programming"',
  'friends_id-friends': 'undefined,"0","1","2"',
  'friends_name-friends':
   'undefined,"Stafford Hernandez","Colleen Christensen","Barker Keith"',
  favoriteFruit: 'undefined,"banana"' }
I want to structure the data in such a way that it would be easy to loop through and produce a csv like this. The issue is that I'm not sure how to make the leap from whats above to whats below.
+--------------------------+-----------------+-------------------+---------------------------------------------+---------------+------------------------+--------------------------+---------------------+-----------------------+---------------+
| _id                      | name            | phone             | address                                     | tags          | Work__skills__id-skill | Work__skills__name-skill | friends__id-friends | friends__name-friends | favoriteFruit |
+--------------------------+-----------------+-------------------+---------------------------------------------+---------------+------------------------+--------------------------+---------------------+-----------------------+---------------+
| 5cfe7d3c6deeeef08ce0444b | Debra Milligain | +1 (906) 432-2182 | 676 Merit Court, Steinhatchee, Oregon, 5491 | consequat     | 0                      | Programming              | 0                   | Stafford Hernandez    | banana        |
+--------------------------+-----------------+-------------------+---------------------------------------------+---------------+------------------------+--------------------------+---------------------+-----------------------+---------------+
|                          |                 |                   |                                             | reprehenderit | Business               |                          | 1                   | Colleen Christensen   |               |
+--------------------------+-----------------+-------------------+---------------------------------------------+---------------+------------------------+--------------------------+---------------------+-----------------------+---------------+
|                          |                 |                   |                                             | amet          |                        |                          | 2                   | Barker Keith          |               |
+--------------------------+-----------------+-------------------+---------------------------------------------+---------------+------------------------+--------------------------+---------------------+-----------------------+---------------+
EDIT: El Tom - possible fix of your code
var arrayOfHeaders = {};
var headerDirectory = "";
var rootLevel = true;
var temp = ""
var firstWalkthrough = true;
traverseJSON(
    JSON.parse('{"_id": "5cfe7d3c6deeeef08ce0444b","name": "Debra Milligain","phone": "+1 (906) 432-2182","address": "676 Merit Court, Steinhatchee, Oregon, 5491","tags": ["consequat","reprehenderit","amet"],"Work": {"skills": [{"id": 0,"name": "Programming"},{"id": 1,"name": "Business"}]},"friends": [{"id": 0,"name": "Stafford Hernandez"},{"id": 1,"name": "Colleen Christensen"},{"id": 2,"name": "Barker Keith"}],"greeting": [],"favoriteFruit": "banana"}')
)
function traverseJSON(obj) {
    for (var o in obj) {
        if (typeof obj[o] == "object") {
            //console.log("Before traversal ", o)
            //console.log("Traversing the object: ", obj[o])
            if (!isNaN(o)) {
                //console.log("Current position is a number ", o)
            } else {
                console.log("Adding to directory... ", o)
                headerDirectory += (headerDirectory == "") ? o : "_" + o;
            }
            rootLevel = false;
            if (firstWalkthrough) {
                firstWalkthrough = false;
                //if (o == 0) 
                rootLevel = true;
            }
            traverseJSON(obj[o]);
            rootLevel = true;
            temp = headerDirectory;
            headerDirectory = "";
        } else {
            if (rootLevel) {
                if (isNaN(o)) {
                    headerDirectory = "";
                    //console.log("Has value and is root ", o, "and temp ", temp)
                    if (arrayOfHeaders[o] !== undefined) {
                        arrayOfHeaders[o].push(obj[o]);
                    } else {
                        arrayOfHeaders[o] = [obj[o]];
                    }
                } else {
                    if (arrayOfHeaders[headerDirectory + "_" + o] !== undefined) {
                        arrayOfHeaders[headerDirectory + "_" + o].push(obj[o]);
                    } else {
                        arrayOfHeaders[headerDirectory + "_" + o] = [obj[o]];
                    }
                }
            }
            else {
                //console.log("Has value and is not root ", o)
                //console.log("Current Header Directory " + headerDirectory)
                //console.log("Saved temp : ", temp)
                if (isNaN(o)) {
                    if (headerDirectory == "") headerDirectory = temp;
                    //arrayOfHeaders.push(headerDirectory + "_" + o)
                    if (arrayOfHeaders[headerDirectory + "_" + o] !== undefined) {
                        arrayOfHeaders[headerDirectory + "_" + o].push(obj[o]);
                    } else {
                        arrayOfHeaders[headerDirectory + "_" + o] = [obj[o]];
                    }
                }
            }
        }
    }
}
var res = JSON.stringify(arrayOfHeaders).replace(/,"/g, ',\n"')
console.log("Easier Arrays in Array printed by JSON.stringify:\n", res)
res = {
    "_id": ["5cfe7d3c6deeeef08ce0444b"],
    "name": ["Debra Milligain"],
    "phone": ["+1 (906) 432-2182"],
    "address": ["676 Merit Court, Steinhatchee, Oregon, 5491"],
    "tags_0": ["consequat"],
    "tags_1": ["reprehenderit"],
    "tags_2": ["amet"],
    "Work_skills_id": [0, 1],
    "Work_skills_name": ["Programming",
        "Business"],
    "friends_id": [0, 1, 2],
    "friends_name": ["Stafford Hernandez",
        "Colleen Christensen",
        "Barker Keith"],
    "favoriteFruit": ["banana"]
};
var yourResult = "";
for(var i in arrayOfHeaders) {
    if(arrayOfHeaders[i].length > 1) {
       arrayOfHeaders[i] = '"' + arrayOfHeaders[i].join('","') + '"';
    } else {
        arrayOfHeaders[i] = '"' + arrayOfHeaders[i] + '"';
    }
    yourResult += i + ':' + arrayOfHeaders[i] + '\n';
}
console.log("\nProbably result you wanted to collect but invalid JSON format:\n", yourResult);But if you compare them with my answer, printed structure is the same, but not as your manualy generated table (probably some errors).
 
    