1

I'm attempting to create one single string from an array of arrays, but with one condition, the last 2 elements (doesn't apply to first row)from the array need to be in "".
The array looks like this:

const data = [
    //( not applied to this row)
    [
        "id",
        "group_name",
        "admin",
        "email_",
        "og.id",
        "created_by.email",
        "students",
        "namesids"
    ],
    //( applied to the following rows)
    [
        "80",
        "Test group",
        "nilton.updated",
        "nilton@crowdform.co.uk",
        "22",
        "nilton@nilton.com",
        "nilton@nilton.com,pedro@com.com",
        "13,14,27"
    ],
    [
        "18",
        "PRO Group",
        "",
        "",
        "22",
        "sys@stys.com",
        "",
        "13000"
    ],
    [
        "10",
        "Test Group",
        "TEst",
        "Test@test.com",
        "22",
        "test.test@test.com",
        "",
        ""
    ]
]

Details:
The data that doesn't contain nothing need to be in quotes too. What I expect, and what I attempted until now:
expected (this is one string, last char from each line is \n):

const this_is_a_string = "
id,group_name,admin,email_,og.id,created_by.email,students,namesids
80,Test group,nilton.updated,nilton@crowdform.co.uk,22,nilton@nilton.com,"nilton@nilton.com,pedro@com.com","13,14,27"
10,Test Group,TEst,Test@test.com,22,test.test@test.com,"",""
...
"

What I attempted, didn't the the right answer:

data.map(objects => {
    const newAr = objects.reduce((arr, values, i) => {        
        arr = arr + ',' + values
        if (i === 6 || i ===7) return arr = arr + ',' + '"' + values + '"';
        return arr;
    }, "")
    console.log(newAr.substring(1));
    return;
})

If possible to create a function that is able to receive the data as first param and an array of position that need to be in quotes. The arrays will always have the same size as the first one, that why I know the positions that need to be in quotes.

Nilton Schumacher F
  • 814
  • 3
  • 13
  • 43
  • 1
    Does this answer your question? [How to export JavaScript array info to csv (on client side)?](https://stackoverflow.com/questions/14964035/how-to-export-javascript-array-info-to-csv-on-client-side) – Tangentially Perpendicular May 04 '22 at 00:41
  • Does the _"last two elements"_ quoting thing apply to the first row or not? – Phil May 04 '22 at 00:44
  • @Phil Doesn't apply to first row, I have updated the question, sorry – Nilton Schumacher F May 04 '22 at 00:45
  • @TangentiallyPerpendicular That doesn't answer the question! – Nilton Schumacher F May 04 '22 at 00:45
  • 1
    CSV has no types, if the parser that consumes this is not complete crap you can just quote every field not just the last two. Also, you need to escape quotes that appear inside the fields using `""` for this to still be valid in case quotes end up in the data. – H.B. May 04 '22 at 00:50
  • 2
    @Nilton Actually, the linked question does answer your question. You're producing a CSV file, even if you don't realise it. The linked question covers exactly that problem. If you think that question doesn't answer your problem then explain _why_ it doesn't, and maybe we can address that. – Tangentially Perpendicular May 04 '22 at 00:54
  • @TangentiallyPerpendicular The formatter that I'm using is different, and the way that the cited answer resulted my data wasn't the way I expected, since I have commas inside of data, it didn't split the data correctly – Nilton Schumacher F May 04 '22 at 00:58

1 Answers1

1

For each row, use Array.prototype.slice() to separate the last two elements from the rest.

Then it's a matter of mapping those last two entries to quoted values and joining everything back up, separated by commas.

Each row can then be joined into a single string separated by newlines.

const data = [["id","group_name","admin","email_","og.id","created_by.email","students","namesids"],["80","Test group","nilton.updated","nilton@crowdform.co.uk","22","nilton@nilton.com","nilton@nilton.com,pedro@com.com","13,14,27"],["18","PRO Group","","","22","sys@stys.com","","13000"],["10","Test Group","TEst","Test@test.com","22","test.test@test.com","",""]];

const rowMapper = (row) =>
  [...row.slice(0, -2), ...row.slice(-2).map((v) => `"${v}"`)].join(",");

const [header, ...rows] = data;

const csv = [header.join(","), ...rows.map(rowMapper)].join("\n");

console.log(csv);

As mentioned in the comments, you might as well quote every value, even the headers and escape any embedded quotes

const csv = data
  .map((row) => row.map((v) => `"${v.replace(/"/g, '""')}"`).join(","))
  .join("\n");
Phil
  • 157,677
  • 23
  • 242
  • 245