0

I have some csv files that I need to parse in JS. The file consists of a bunch of rows, which I need to pull out two. One has the headers for this card, the next row is the data.

I am trying to use csv-parse and have managed to unpack the data into json objects, but can't for the life of me work out how to make this work.

I tried regex but of course csv-parse returns objects, not rows as strings.

The files in question have lots of stuff in them. The rows I'm interested in have rows like

H,TYPE1,TYPE2,field,field,field.....
followed by
D,TYPE1,TYPE2,value,value,value....

The result I'm looking for is a json object with field1:value1, field2:value2 etc.

Whats the best way to do this?

I thought about an arrayAll function to pull out the array with the right fields, but csv-parse returns objects not arrays.. sigh.

I'm sure I'm making this harder than it need to be.

1 Answer 1

1

You could simply pre-process the file to extract the relevant content (e.g. the two lines you're interested, then pass this to csv-parse),

For example:

const parse = require("csv-parse");
const fs = require("fs");

const filePath = "inline-headers.csv";
const csvContent = getRequiredCsvContent(filePath);

function getRequiredCsvContent(filePath) {
    // Replace with your actual regex pattern...
    let lineMatcher = /header/i;
    let fileLines = fs.readFileSync(filePath, "utf8").split("\n");
    let requiredLines = fileLines.reduce((contentArray, line, index) => { 
        if (lineMatcher.test(line) || (contentArray.length === 1)) {
            contentArray.push(line);
        }
        return contentArray;
    }, []);
    return requiredLines.join("\n");
}

console.log("Extracted csv content:\n", csvContent);
parse(csvContent, {
    delimiter: ",",
    columns: true
}, (err, records) => {
    if (err) {
        console.error("An error occurred:", err);
    } else { 
        console.log("Records:", records);
    }
});

I'm using a test file like so:

inline-headers.csv

someline01,someline02,someline03
someline11,someline12,someline13
header1,header2,header3
field1,field2,field3

I'm including a more specific answer here that's more tailored to your actual problem:

const parse = require("csv-parse");
const fs = require("fs");
const filePath = "inline-headers.csv";
const csvContent = getRequiredCsvContent(filePath);

function getRequiredCsvContent(filePath) {
    const lineMatcher = /^(I|D),DISPATCH,UNIT_SOLUTION/;
    let fileLines = fs.readFileSync(filePath, "utf8").split("\n");
    let requiredLines = fileLines.reduce((contentArray, line) => {
        if (lineMatcher.test(line) || (contentArray.length === 1)) {
            contentArray.push(line);
        }
        return contentArray;
    }, []);
    return requiredLines.join("\n")
}

console.log("Extracted csv content:\n", csvContent);
parse(csvContent, {
    delimiter: ",",
    columns: true,
    relax_column_count: true
}, (err, records) => {
    if (err) {
        console.error("Error:", err);
    } else {
        console.log("Records:", records);
    }
});
Sign up to request clarification or add additional context in comments.

7 Comments

I'm close. I have the correct two lines in csvContent but the parse command (I had to use parse = require("csv-parse") rather than "csv-parse/lib/sync" if that matters. Unfortunately rather than unpacking the full words for the header columns, it unpacked each character into its own if that makes sense.
I'll see if I can replicate that behaviour, then I might be able to find a workaround / fix!
Thanks Terry, I can send you the file I'm testing against with the code I've come up with if that helps.. not sure if you can pm on here though.
Ah yes, we can just do a trim on the fields and we should be ok. Reduce a very useful function, you can do an awful lot with it!
Yep.. that did it :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.