Transform CSV into an Array of Objects

230 views Asked by At

I have a CSV file like this one below, I must take some different values from it, but I'm struggling in transform this CSV into an array of Objects

"+++++++++ 1.2 LifeTime Cost and Emissions +++++++++","<TABLE>"
" ","year1","year2","year3","year4","year5","year6","year7","year8","year9","year10","year11","year12","year13","year14","year15","year16","year17","year18","year19","year20","year21","year22","year23","year24","year25","<HEADER>"
"Total Annual Energy Costs (incl. annualized capital costs and electricity sales) ($)",-560.9845,353.4204,451.6855,514.2567,523.2091,572.8177,622.6726,632.3996,642.4129,652.7211,663.3330,674.2575,1458.1040,617.1780,661.0587,692.5061,705.1385,732.5260,760.2972,774.0806,788.2706,802.8795,817.9194,833.4033,849.3444
"Total Annual CO2 emissions (kg)",387734.0330,387734.0330,387736.8925,387736.8925,387736.8925,387738.4191,387738.4191,387738.4191,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886
"Levelized Cost Of Energy ($/kWh)",-0.1738,0.1095,0.1404,0.1598,0.1626,0.1786,0.1942,0.1972,0.2003,0.2035,0.2069,0.2103,0.4547,0.1925,0.2061,0.2159,0.2199,0.2284,0.2371,0.2414,0.2458,0.2504,0.2551,0.2599,0.2649

I've tryed this:

const csvFilePath = 'Result_Lifetime002.csv';
const json = await csvToJson().fromFile(csvFilePath);
const jsonString = JSON.stringify(json, null, 2);

But it returns a big string with an array in it.

Anyway, the expected result should be something like this (just taking the item 1.2 as an example):

const result = [
    {
        "+++++++++ 1.2 LifeTime Cost and Emissions +++++++++":"Total Annual Energy Costs (incl. annualized capital costs and electricity sales) ($)",
        "year1": -560.9845,
        "year2": 353.4204,
        "year3": 451.6855,
        "year4": 514.2567,
        "year5": 523.2091,
        "year6": 572.8177,
        "year7": 622.6726,
        "year8": 632.3996,
        "year9": 642.4129,
        "year10": 652.7211,
        "year11": 663.3330,
        "year12": 674.2575,
        "year13": 1458.1040,
        "year14": 617.1780,
        "year15": 661.0587,
        "year16": 692.5061,
        "year17": 705.1385,
        "year18": 732.5260,
        "year19": 760.2972,
        "year20": 774.0806,
        "year21": 788.2706,
        "year22": 802.8795,
        "year23": 817.9194,
        "year24": 833.4033,
        "year25": 849.3444
    },
    {
        "+++++++++ 1.2 LifeTime Cost and Emissions +++++++++":"Total Annual CO2 emissions (kg)",
        "year1": 387734.0330,
        "year2": 387734.0330,
        "year3": 387736.8925,
        "year4": 387736.8925,
        "year5": 387736.8925,
        "year6": 387738.4191,
        "year7": 387738.4191,
        "year8": 387738.4191,
        "year9": 387738.8886,
        "year10": 387738.8886,
        "year11": 387738.8886,
        "year12": 387738.8886,
        "year13": 387738.8886,
        "year14": 387738.8886,
        "year15": 387738.8886,
        "year16": 387738.8886,
        "year17": 387738.8886,
        "year18": 387738.8886,
        "year19": 387738.8886,
        "year20": 387738.8886,
        "year21": 387738.8886,
        "year22": 387738.8886,
        "year23": 387738.8886,
        "year24": 387738.8886,
        "year25": 387738.8886,
    },
    {
        "+++++++++ 1.2 LifeTime Cost and Emissions +++++++++":"Levelized Cost Of Energy ($/kWh)",
        "year1": -0.1738,
        "year2": 0.1095,
        "year3": 0.1404,
        "year4": 0.1598,
        "year5": 0.1626,
        "year6": 0.1786,
        "year7": 0.1942,
        "year8": 0.1972,
        "year9": 0.2003,
        "year10": 0.2035,
        "year11": 0.2069,
        "year12": 0.2103,
        "year13": 0.4547,
        "year14": 0.1925,
        "year15": 0.2061,
        "year16": 0.2159,
        "year17": 0.2199,
        "year18": 0.2284,
        "year19": 0.2371,
        "year20": 0.2414,
        "year21": 0.2458,
        "year22": 0.2504,
        "year23": 0.2551,
        "year24": 0.2599,
        "year25": 0.2649
    }
]
1

There are 1 answers

1
FiddlingAway On BEST ANSWER

Would something like this work for you?

For simplicity's sake, I've placed the contents of your CSV inside a variable, and skipped the steps of reading the file (I'll give this code at very end). Please note that there are most likely more optimal ways of dealing with this, but I decided on going with this solution, since I could break it down into simple steps.

var data = `
+++++++++ 1.2 LifeTime Cost and Emissions +++++++++,<TABLE>
 ,year1,year2,year3,year4,year5,year6,year7,year8,year9,year10,year11,year12,year13,year14,year15,year16,year17,year18,year19,year20,year21,year22,year23,year24,year25,<HEADER>
Total Annual Energy Costs (incl. annualized capital costs and electricity sales) ($),-560.9845,353.4204,451.6855,514.2567,523.2091,572.8177,622.6726,632.3996,642.4129,652.7211,663.3330,674.2575,1458.1040,617.1780,661.0587,692.5061,705.1385,732.5260,760.2972,774.0806,788.2706,802.8795,817.9194,833.4033,849.3444
Total Annual CO2 emissions (kg),387734.0330,387734.0330,387736.8925,387736.8925,387736.8925,387738.4191,387738.4191,387738.4191,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886,387738.8886
Levelized Cost Of Energy ($/kWh),-0.1738,0.1095,0.1404,0.1598,0.1626,0.1786,0.1942,0.1972,0.2003,0.2035,0.2069,0.2103,0.4547,0.1925,0.2061,0.2159,0.2199,0.2284,0.2371,0.2414,0.2458,0.2504,0.2551,0.2599,0.2649
`;

// Create an array by splitting the CSV by newline
data = data.trim().split(/\r?\n/);

// Extract the first index, since we want to repeat it later on as
// the first key of every JSON element of your resulting array
// This is the long string with the pluses
/* remove this multiline comment to see the contents of data[0]
console.log(data[0]);
*/
var title = data[0].split(",")[0];

// Extract the other main keys - years
var innerKeys = data[1].trim().split(",");

// Remove the the last one, since we don't need it - <HEADER>
innerKeys.pop();

// Prepare the array for our results
var results = [];

// Loop through indivdual rows, and split by comma / ,
// We'll skip the first two, since we've dealt with them
// data[0] being the row with the long string with the pluses
// and data[1] being the row containing the years

for(var i = 2; i < data.length; i++) {
    // Let's clean any trailing empty characters
    var tempRow = data[i].trim();

    // If there's anything we can work with
    if(tempRow) {
        // Create an array from the values in the current line
        tempRow = tempRow.split(",");

        // Let's get the value for our first keys
        // These are the Total Annual etc strings from your CSV
        var tempTitle = tempRow[0];

        // Let's declare and fill our temp object
        var innerJSON = {};

        // The first key is the one with the pluses
        // and its value is the Total Annual etc string
        innerJSON[title] = tempTitle;
        for(var j = 1; j < tempRow.length; j++) {
            // Let's fill the years and give them matching values
            innerJSON[innerKeys[j]] = tempRow[j];
        }

        // All done, add it to the resulting array
        results.push(innerJSON);
    }
}

console.log(results);

Now, if we were to read the contents of the data variable from you CSV, using FileReader object would do the trick. You could implement it like this.

var data = "";
var reader = new FileReader();
// I'm assuming you have an input element, whose type is file
// and that you read from it
reader = readAsText(document.getElementById("myFileInput").files[0]);

reader.addEventListener('load',function() {
    data = reader.result;
    parseData(data);
});

where parseData(data) would be a function doing all of the things shown in the first part of my answer (splitting your CSV into an array, looping, etc). Try it out below.

const file = document.getElementById("file");
const parse = document.getElementById("parse");
var data = "";

parse.addEventListener("click", readFile);

function readFile() {
  let reader = new FileReader();
  reader.readAsText(file.files[0]);
  
  reader.addEventListener('load', function(e) { 
    data = reader.result;
    
    parseData(data);
  });
}

function parseData(data) {
  // Let's remove the quotes first - you don't have to do this
  // if it's absolutely necessary to keep them
    data = data.replaceAll("\"","");
  // Create an array by splitting the CSV by newline
  data = data.trim().split(/\r?\n/);

  // Extract the first index, since we want to repeat it later on as
  // the first key of every JSON element of your resulting array
  // This is the long string with the pluses
  /* remove this multiline comment to see the contents of data[0]
  console.log(data[0]);
  */
  var title = data[0].split(",")[0];

  // Extract the other main keys - years
  var innerKeys = data[1].trim().split(",");

  // Remove the the last one, since we don't need it - <HEADER>
  innerKeys.pop();

  // Prepare the array for our results
  var results = [];

  // Loop through indivdual rows, and split by comma / ,
  // We'll skip the first two, since we've dealt with them
  // data[0] being the row with the long string with the pluses
  // and data[1] being the row containing the years

  for(var i = 2; i < data.length; i++) {
      // Let's clean any trailing empty characters
      var tempRow = data[i].trim();

      // If there's anything we can work with
      if(tempRow) {
          // Create an array from the values in the current line
          tempRow = tempRow.split(",");

          // Let's get the value for our first keys
          // These are the Total Annual etc strings from your CSV
          var tempTitle = tempRow[0];

          // Let's declare and fill our temp object
          var innerJSON = {};

          // The first key is the one with the pluses
          // and its value is the Total Annual etc string
          innerJSON[title] = tempTitle;
          for(var j = 1; j < tempRow.length; j++) {
              // Let's fill the years and give them matching values
              innerJSON[innerKeys[j]] = tempRow[j];
          }

          // All done, add it to the resulting array
          results.push(innerJSON);
      }
  }

  console.log(results);
}
<input type="file" id="file">
<button type="button" id="parse">Parse</button>