CSV to JSON list of arrays

677 Views Asked by At

My csv is like this, only have numbers. No headers. I have to identify the name of each column in the javascprit (node.js) code.

1364.00,0.15,0.36,-0.13,-3.24,-0.42,-0.15,0.90,0.00,-0.01,0.02,0.26,0.01,-0.04
1374.00,0.30,0.76,-0.25,-3.25,-0.41,-0.13,0.91,0.00,-0.00,0.02,0.26,0.01,-0.04
1384.00,0.45,1.08,-0.35,-3.17,-0.41,-0.10,1.00,-0.00,-0.01,0.02,0.26,0.01,-0.07

node js code


    const csvFilePath = "test - Cópia.csv"
    
    const csvtojsonV2=require('csvtojson')
    csvtojsonV2({
        noheader:true,
        checkType:true,    
        headers:["Time","Yaw","Pitch","Roll","Heading","Ax", "Ay", "Az","Gx","Gy", "Gz", "Mx", "My", "Mz"],
        colParser:{        
            "column1": Int32Array,
            "column2":Int32Array,
            "column3":Int32Array,
            "column4":Int32Array,
            "column5":Int32Array,
            "column6":Int32Array,
            "column7":Int32Array,
            "column8":Int32Array,
            "column9":Int32Array,
            "column10":Int32Array,
            "column11":Int32Array,
            "column12":Int32Array,
            "column13":Int32Array,
            "column14":Int32Array},
            
        
    })
    .fromFile(csvFilePath)
    .then((json) => {
        console.log(json)  
    }) 

and the result that i obtain with the code above is this json:

[
      {
        Time: 1364,
        Yaw: 0.15,
        Pitch: 0.36,
        Roll: -0.13,
        Heading: -3.24,
        Ax: -0.42,
        Ay: -0.15,
        Az: 0.9,
        Gx: 0,
        Gy: -0.01,
        Gz: 0.02,
        Mx: 0.26,
        My: 0.01,
        Mz: -0.04
      },
      {
        Time: 1374,
        Yaw: 0.3,
        Pitch: 0.76,
        Roll: -0.25,
        Heading: -3.25,
        Ax: -0.41,
        Ay: -0.13,
        Az: 0.91,
        Gx: 0,
        Gy: -0,
        Gz: 0.02,
        Mx: 0.26,
        My: 0.01,
        Mz: -0.04
      },
      {
        Time: 1384,
        Yaw: 0.45,
        Pitch: 1.08,
        Roll: -0.35,
        Heading: -3.17,
        Ax: -0.41,
        Ay: -0.1,
        Az: 1,
        Gx: -0,
        Gy: -0.01,
        Gz: 0.02,
        Mx: 0.26,
        My: 0.01,
        Mz: -0.07
      }
    ]

I want a little different, like this(bewlow: Each Column a dictionary of arrays.

{"Time": [1364.0, 1374.0, 1384.0], 
"Yaw": [0.15, 0.3, 0.45], 
"Pitch": [0.36, 0.76, 1.08], 
"Heading": [-0.13, -0.25, -0.35], 
"Roll": [-3.24, -3.25, -3.17], 
"Ax": [-0.42, -0.41, -0.41], 
"Ay": [-0.15, -0.13, -0.1], 
"Az": [0.9, 0.91, 1.0], 
"Gx": [0.0, 0.0, -0.0], 
"Gy": [-0.01, -0.0, -0.01], 
"Gz": [0.02, 0.02, 0.02], 
"Mx": [0.26, 0.26, 0.26], 
"My": [0.01, 0.01, 0.01], 
"Mz": [-0.04, -0.04, -0.07]} 
1

There are 1 best solutions below

2
On BEST ANSWER

First method

Using your code, which uses the csvtojson library, you can just add this:

    const csvFilePath = "test - Cópia.csv"
    
    const csvtojsonV2=require('csvtojson')
    csvtojsonV2({
        noheader:true,
        checkType:true,    
        headers:["Time","Yaw","Pitch","Roll","Heading","Ax", "Ay", "Az","Gx","Gy", "Gz", "Mx", "My", "Mz"],
        colParser:{        
            "column1": Int32Array,
            "column2":Int32Array,
            "column3":Int32Array,
            "column4":Int32Array,
            "column5":Int32Array,
            "column6":Int32Array,
            "column7":Int32Array,
            "column8":Int32Array,
            "column9":Int32Array,
            "column10":Int32Array,
            "column11":Int32Array,
            "column12":Int32Array,
            "column13":Int32Array,
            "column14":Int32Array},
            
        
    })
    .fromFile(csvFilePath)
    .then((json) => {
       const RESULT = json.reduce((acc, v, i) => {
          for (const [key, value] of Object.entries(v)) {
            if (!acc[key]) acc[key] = [];
            acc[key].push(value);
          }
          return acc;
        }, {});
       console.log(RESULT)
    }) 

What it does is to accumulate the data in acc variable, using each rows' keys these keys being the header, as you can see in acc[key].push(value), the if (!acc[key]) acc[key] = [] is to make sure the heading is initializied with an empty array in the acc variable (accumulator);

Second method

This doesn't use any library:

// Arbitrary data (from you example).
const DATA = `1364.00,0.15,0.36,-0.13,-3.24,-0.42,-0.15,0.90,0.00,-0.01,0.02,0.26,0.01,-0.04
1374.00,0.30,0.76,-0.25,-3.25,-0.41,-0.13,0.91,0.00,-0.00,0.02,0.26,0.01,-0.04
1384.00,0.45,1.08,-0.35,-3.17,-0.41,-0.10,1.00,-0.00,-0.01,0.02,0.26,0.01,-0.07
`.trim().split('\n').map(row => row.split(','));

const HEADERS = ["Time", "Yaw", "Pitch", "Roll", "Heading", "Ax", "Ay", "Az", "Gx", "Gy", "Gz", "Mx", "My", "Mz"];

const RESULT = {};

// Assign every heading to the result.
for (const HEADING of HEADERS) RESULT[HEADING] = [];

DATA.map(row =>
  // Each row → each column, number of columns === number of headers
  row.map((column, i) =>
    RESULT[HEADERS[i]]
    .push(Number(column))
  )
);

console.log(RESULT);

Explanation of each step:

  1. Assuming that the CSV's contents separates rows with "\n" and the preferred column separator is ",", I set up an arbitrary data contents;
  2. A constant HEADERS is created, the headers must be the same length of the CSV's data columns;
  3. A constant RESULT is created, this will store the result of the parsed data to JSON.
  4. We initialize the keys of RESULT with the defined HEADERS with an empty array;
  5. We map the data from each row then each column, using the column's index to refer to the current heading in our HEADERS array, since the length of the columns are expected to be equal to the length of the HEADERS constant.

If you must keep the trailing zeroes (e.g.: 15.00) of the numbers, then you can just remove Number() method from Number(column) inside the .push() method before inserting into the result array.