Home > Mobile >  display array in specific format in a table
display array in specific format in a table

Time:09-26

i have this array

const arr = [
        { sum: 77, shift:  1, date: "2020-07-05T00:00:00" },

        { sum: 25, shift:  2, date: "2020-07-05T00:00:00" },

        { sum: 10, shift:  3, date: "2020-07-05T00:00:00" },

        { sum: 13, shift:  1, date: "2020-07-06T00:00:00" },

        { sum: 66, shift:  2, date: "2020-07-06T00:00:00" },

        { sum: 30, shift:  3, date: "2020-07-06T00:00:00" },

        { sum: 50, shift:  1, date: "2020-07-06T00:00:00" },

        { sum: 40, shift:  2, date: "2020-07-07T00:00:00" },

        { sum: 65, shift:  3, date: "2020-07-07T00:00:00" },
      ];

i want to display a table in this format like this :

DATE SHIFT 1 SHIFT2 SHIFT3

07-05-2020   77   25  10
07-06-2020   13   66  30
07-07-2020   50   40  65

i want to groupe shifts in table by date

CodePudding user response:

You can generate the mentioned table with the underlying code:

const arr = [
        { sum: 77, shift: 1, date: "2020-07-05T00:00:00" },

        { sum: 25, shift: 2, date: "2020-07-05T00:00:00" },

        { sum: 10, shift: 3, date: "2020-07-05T00:00:00" },

        { sum: 13, shift: 1, date: "2020-07-06T00:00:00" },

        { sum: 66, shift: 2, date: "2020-07-06T00:00:00" },

        { sum: 30, shift: 3, date: "2020-07-06T00:00:00" },

        { sum: 50, shift: 1, date: "2020-07-06T00:00:00" },

        { sum: 40, shift: 2, date: "2020-07-07T00:00:00" },

        { sum: 65, shift: 3, date: "2020-07-07T00:00:00" },
    ];

    const groups = arr.reduce((groups, arrItem) => {
        const date = arrItem.date.split('T')[0];
        if (!groups[date]) {
            groups[date] = [];
        }
        groups[date].push(arrItem.sum);
        return groups;
    }, {});

    const groupArrays = Object.keys(groups).map((date) => {
        return {
            date,
            sum: groups[date]
        };
    });

    var result = "<table border=1>";
    for (var i = 0; i < groupArrays.length; i  ) {
        result  = "<tr>";
        result  = "<td>"   groupArrays[i].date   "</td>";
        for (var j = 0; j < groupArrays[i].sum.length; j  ) {
            result  = "<td>"   groupArrays[i].sum[j]   "</td>";
        }
        result  = "</tr>";
    }
    result  = "</table>";

    return result;

I hope this helps.

CodePudding user response:

This is a demo to group you array containing shifts (indexed) values by datetime.

There's a function to fetch the grouped data from the input array and a function to render that grouped data in a given table defined in the html with a given id.

Some assumptions were made like the number of shifts value.

If there's some missing shift id value, it will be rendered as undefined.

You probably made a typo in your input data when saying this:

{ sum: 50, shift: 1, date: "2020-07-06T00:00:00" },

it will overwrite the shift number 1 previously defined for the same datetime. I left it untouched anyway.

The grouping is made by looping through the input array and populating an object using the datetime as the key and as value an ordered list of values where the index is the shift number.

The datetime formats get transformed using a dedicated function involving regular expressions.

const arr = [
  { sum: 77, shift:  1, date: "2020-07-05T00:00:00" },
  { sum: 25, shift:  2, date: "2020-07-05T00:00:00" },
  { sum: 10, shift:  3, date: "2020-07-05T00:00:00" },
  { sum: 13, shift:  1, date: "2020-07-06T00:00:00" },
  { sum: 66, shift:  2, date: "2020-07-06T00:00:00" },
  { sum: 30, shift:  3, date: "2020-07-06T00:00:00" },
  { sum: 50, shift:  1, date: "2020-07-06T00:00:00" },
  { sum: 40, shift:  2, date: "2020-07-07T00:00:00" },
  { sum: 65, shift:  3, date: "2020-07-07T00:00:00" },
];

function transformDateTime(raw){
  match = raw.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/im);
  if (match != null) {
    return `${match[2]}-${match[3]}-${match[1]}`;
  }
}

function group(shifts){
  const grouped = {};
  for(shift of shifts){
    let datetime = shift.date.substring(0, 10);
    datetime = transformDateTime(datetime);
    if (!grouped.hasOwnProperty(datetime))
      grouped[datetime] = [];      
    grouped[datetime][shift.shift-1] = shift.sum;
  }
  return grouped;
}

function renderGrouped(grouped){
  const tbody = document.querySelector('#shifts > tbody');
  for(const [datetime, shift] of Object.entries(grouped)){
    const shiftRow = document.createElement('tr');
    const datetimeCell = document.createElement('td');
    shiftRow.append(datetimeCell);
    datetimeCell.innerText = datetime;
    for(let i=0;i<shift.length;i  ){
      const shiftCell = document.createElement('td');
      shiftCell.innerText = shift[i];
      shiftRow.append(shiftCell);
    }
    tbody.append(shiftRow);
  }  
}

const grouped = group(arr);
renderGrouped(grouped);
//console.log(grouped);
<table id="shifts">
  <thead>
    <th>DateTime</th>
    <th>SHIFT1</th>
    <th>SHIFT2</th>
    <th>SHIFT3</th>
  </thead>
  <tbody>
  </tbody>
</table>

CodePudding user response:

I would suggest using Array.reduce() to group the input by date and shift.

Once we have grouped the input, we'll iterate over the grouped data using for .. in and append to the output table.

const arr = [ { sum: 77, shift:  1, date: "2020-07-05T00:00:00" },  { sum: 25, shift:  2, date: "2020-07-05T00:00:00" },  { sum: 10, shift:  3, date: "2020-07-05T00:00:00" },  { sum: 13, shift:  1, date: "2020-07-06T00:00:00" },  { sum: 66, shift:  2, date: "2020-07-06T00:00:00" },  { sum: 30, shift:  3, date: "2020-07-06T00:00:00" },  { sum: 50, shift:  1, date: "2020-07-07T00:00:00" },  { sum: 40, shift:  2, date: "2020-07-07T00:00:00" },  { sum: 65, shift:  3, date: "2020-07-07T00:00:00" }, ];

const grouped = arr.reduce((acc, { sum, shift, date }) => {
    let dateKey = date.slice(0,10); 
    acc[dateKey] = acc[dateKey] || {};
    acc[dateKey][shift] = sum;
    return acc;
}, {})

function appendChildElement(element, tagName, innerText) {
    let child = document.createElement(tagName);
    if (innerText) child.innerText = innerText;
    return element.appendChild(child);
}

for(let date in grouped) {
    let row = appendChildElement(document.getElementById('output'), 'tr');
    appendChildElement(row, 'td', date);
    for(let shift in grouped[date]) {
        appendChildElement(row, 'td', grouped[date][shift]);
    }
}
<table >
  <thead>
<tr>
  <th scope="col">Date</th>
  <th scope="col">Shift 1</th>
  <th scope="col">Shift 2</th>
  <th scope="col">Shift 3</th>
</tr>
  </thead>
  <tbody id="output">
  </tbody>
</table>
  
<!-- Bootstrap Styling -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA 058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  • Related