JSON Multidimensional Array to HTML Table

I have a condition that require me to make a html table using json multidimensional. This is the sample of my JSON Data

let year = [
  {
    ym : "202006",
    data : [
       {
         202007: "100", 
         202008: "100", 
         202009: "100", 
         202010: "100", 
         202011: "96.71", 
         202012: "100", 
         202101: "100", 
         202102: "96.43"
       }
    ]
  }
];

And this is my expected result

enter image description here

I already managed to create the table header using loop. But i find it difficult when generating table data using this JSON Data. Any kind of help will be really appriciated . Thank you

EDIT :

I was able to generate the table header using original data . The code i was using is

result = arr.reduce(function (r, a) {
    r[a.TIME_PERIOD_HEADER] = r[a.TIME_PERIOD_HEADER] || [];
    r[a.TIME_PERIOD_HEADER].push(a);
    return r;
}, Object.create(null));

var keys = Object.keys(result);

keys.map((value, index) => {
  $('#tbl_row').append('<th>'+value+'</th>')
})

After i generated the table header, i tried to modify the original json array into a new json array using :

var o = arr.reduce( (a,b) => {
  a[b.TIME_PERIOD] = a[b.TIME_PERIOD] || [];
  a[b.TIME_PERIOD].push({[b.TIME_PERIOD_DATA]:b.PERCENT});
  return a;
}, {});

var a = Object.keys(o).map(function(k) {
  var m = Object.assign.apply({},o[k]);
    keys.forEach( (x) => { if ( !(x in m) ) m[x] = 0 });
    
    return {TIME_PERIOD: k, TIME_PERIOD_DATA: m};
});
//this code produce the first JSON data (let year = ....)

1 answer

  • answered 2021-06-23 08:20 ceving

    The following snippet ignores that data is an array, because your expected output ignores it, too.

    let year = [
      {
        ym : "202006",
        data : [
           {
             202007: "100", 
             202008: "100", 
             202009: "100", 
             202010: "100", 
             202011: "96.71", 
             202012: "100", 
             202101: "100", 
             202102: "96.43"
           }
        ]
      }
    ];
    
    let columns = year
      .map (y => y.data)
      .flat (1)
      .map (d => Object.keys(d))
      .flat (1)
      .sort ()
      .filter ((x, i, a) => !i || x != a[i-1]);
    
    document.write ('<table><tdata>');
    document.write ('<tr style="text-transform: uppercase">');
    document.write ('<th rowspan="2">time period</th>');
    document.write (`<th colspan=${columns.length}>time period data</th>`);
    document.write ('</tr></tr>');
    for (const c of columns) {
      document.write (`<td>${c}</td>`);
    }
    document.write ('</tr>');
    for (const y of year) {
      document.write (`<tr><td>${y.ym}</td>`);
      for (const c of columns) {
        document.write (`<td>${y.data[0][c]}</td>`);
      }
      document.write ('</tr>');
    }
    document.write ('<tdata><table>');

    The idea is: iterated over all your data to calculate the column list. After that iterate over the years and for each year iterate over the columns to pick the right value from the data for the column. The filter after the sort makes the sorted list unique, because the code collects all columns from all data objects.