Skip to content Skip to sidebar Skip to footer

Transform Json By Grouping By Date And Thereafter By Datetime In Nodejs

I have a JSON of IoT readings as follow: [ { 'datetime': '2020-06-29T23:59:59.000Z', 'Benzene': 1.9 }, { 'datetime': '2020-06-30T00:59:59.000Z',

Solution 1:

You could take two hash table for long and short date and get the short date's values.

For getting a deeper understanding, you could have a look to the r object which contains two properties long and short.

{
    long: {
        "2020-06-29T23:59:59.000Z": {              //id:3t:"2020-06-29T23:59:59.000Z",
            Benzene:1.9,
            O3:25.6
        },
        "2020-06-30T00:59:59.000Z": {              //id:4t:"2020-06-30T00:59:59.000Z",
            Benzene:0.6,
            NO2:16.3
        },
        "2020-06-30T01:59:59.000Z": {              //id:5t:"2020-06-30T01:59:59.000Z",
            Benzene:5.7,
            NO2:12.6,
            O3:31.7
        },
        //...
    },
    short: {
        "2020-06-29": {
            date:"2020-06-29",
            values: [
                {                                  //ref:3,
                    t:"2020-06-29T23:59:59.000Z",
                    Benzene:1.9,
                    O3:25.6
                }
            ]
        },
        "2020-06-30": {
            date:"2020-06-30",
            values: [
                {                                  //ref:4,
                    t:"2020-06-30T00:59:59.000Z",
                    Benzene:0.6,
                    NO2:16.3
                },
                {                                  //ref:5,
                    t:"2020-06-30T01:59:59.000Z",
                    Benzene:5.7,
                    NO2:12.6,
                    O3:31.7
                }
            ]
        },
        //...
    }
}

long contains objects for collecting the properties for a lonmg timestamp and pushes this object to the corresponding short collection which is grouped by the short date of a day.

In the short property, all objects are finaly part of the result set, with grouped day data and grouped by timestamp, the long date.

var data = [{ datetime: "2020-06-29T23:59:59.000Z", Benzene: 1.9 }, { datetime: "2020-06-30T00:59:59.000Z", Benzene: 0.6 }, { datetime: "2020-06-30T01:59:59.000Z", Benzene: 5.7 }, { datetime: "2020-06-30T02:59:59.000Z", Benzene: 5.5 }, { datetime: "2020-06-30T03:59:59.000Z", Benzene: 5.2 }, { datetime: "2020-06-30T04:59:59.000Z", Benzene: 1 }, { datetime: "2020-06-30T05:59:59.000Z", Benzene: 2.1 }, { datetime: "2020-06-30T06:59:59.000Z", Benzene: 4.2 }, { datetime: "2020-06-30T07:59:59.000Z", Benzene: 3.4 }, { datetime: "2020-06-30T00:59:59.000Z", NO2: 16.3 }, { datetime: "2020-06-30T01:59:59.000Z", NO2: 12.6 }, { datetime: "2020-06-30T02:59:59.000Z", NO2: 11.7 }, { datetime: "2020-06-30T03:59:59.000Z", NO2: 35.5 }, { datetime: "2020-06-30T04:59:59.000Z", NO2: 44.6 }, { datetime: "2020-06-30T05:59:59.000Z", NO2: 19.9 }, { datetime: "2020-06-30T06:59:59.000Z", NO2: 11.2 }, { datetime: "2020-06-30T07:59:59.000Z", NO2: 8.2 }, { datetime: "2020-06-29T23:59:59.000Z", O3: 25.6 }, { datetime: "2020-06-30T01:59:59.000Z", O3: 31.7 }, { datetime: "2020-06-30T02:59:59.000Z", O3: 35.1 }, { datetime: "2020-06-30T03:59:59.000Z", O3: 11.4 }, { datetime: "2020-06-30T04:59:59.000Z", O3: 4.9 }, { datetime: "2020-06-30T05:59:59.000Z", O3: 32.8 }, { datetime: "2020-06-30T06:59:59.000Z", O3: 46.4 }, { datetime: "2020-06-30T07:59:59.000Z", O3: 55.6 }],
    result = Object.values(data
        .reduce((r, { datetime: t, ...o }) => {
            let date = t.slice(0, 10);
            if (!r.long[t]) {
                r.short[date] = r.short[date] || { date, values: [] };
                r.short[date].values.push(r.long[t] = { t });
            }
            Object.assign(r.long[t], o);
            return r;
        }, { long: {}, short: {} })
        .short
    );

console.log(result);
.as-console-wrapper { max-height: 100%!important; top: 0; }

Solution 2:

I would suggest using momentjs(https://momentjs.com/). It's a library that contains many utils for dealing with dates and times, I strongly recommend it!

Here is an example:

const exampleData = [{
    "datetime": "2020-06-29T23:59:59.000Z",
    "Benzene": 1.9
  },
  {
    "datetime": "2020-06-30T00:59:59.000Z",
    "Benzene": 0.6
  },
  {
    "datetime": "2020-06-30T01:59:59.000Z",
    "Benzene": 5.7
  },
  {
    "datetime": "2020-06-30T02:59:59.000Z",
    "Benzene": 5.5
  },
  {
    "datetime": "2020-06-30T03:59:59.000Z",
    "Benzene": 5.2
  },
  {
    "datetime": "2020-06-30T04:59:59.000Z",
    "Benzene": 1
  },
  {
    "datetime": "2020-06-30T05:59:59.000Z",
    "Benzene": 2.1
  },
  {
    "datetime": "2020-06-30T06:59:59.000Z",
    "Benzene": 4.2
  },
  {
    "datetime": "2020-06-30T07:59:59.000Z",
    "Benzene": 3.4
  },
  {
    "datetime": "2020-06-30T00:59:59.000Z",
    "NO2": 16.3
  },
  {
    "datetime": "2020-06-30T01:59:59.000Z",
    "NO2": 12.6
  },
  {
    "datetime": "2020-06-30T02:59:59.000Z",
    "NO2": 11.7
  },
  {
    "datetime": "2020-06-30T03:59:59.000Z",
    "NO2": 35.5
  },
  {
    "datetime": "2020-06-30T04:59:59.000Z",
    "NO2": 44.6
  },
  {
    "datetime": "2020-06-30T05:59:59.000Z",
    "NO2": 19.9
  },
  {
    "datetime": "2020-06-30T06:59:59.000Z",
    "NO2": 11.2
  },
  {
    "datetime": "2020-06-30T07:59:59.000Z",
    "NO2": 8.2
  },
  {
    "datetime": "2020-06-29T23:59:59.000Z",
    "O3": 25.6
  },
  {
    "datetime": "2020-06-30T01:59:59.000Z",
    "O3": 31.7
  },
  {
    "datetime": "2020-06-30T02:59:59.000Z",
    "O3": 35.1
  },
  {
    "datetime": "2020-06-30T03:59:59.000Z",
    "O3": 11.4
  },
  {
    "datetime": "2020-06-30T04:59:59.000Z",
    "O3": 4.9
  },
  {
    "datetime": "2020-06-30T05:59:59.000Z",
    "O3": 32.8
  },
  {
    "datetime": "2020-06-30T06:59:59.000Z",
    "O3": 46.4
  },
  {
    "datetime": "2020-06-30T07:59:59.000Z",
    "O3": 55.6
  },
  {
    "datetime": "2020-06-20T07:59:59.000Z",
    "O3": 14.6
  },
  {
    "datetime": "2020-06-20T07:59:59.000Z",
    "Benzene": 14.6
  }
]

const keyFormat = "YYYY-MM-DD"constgroupReadings = (readings) => {
  const groups = []
  readings.forEach(reading => {
    const dateMoment = moment(reading.datetime)
    const dateKey = dateMoment.format(keyFormat)

    let dateData = groups.find(x => x.date === dateKey)
    if (!dateData) {
      dateData = {
        date: dateKey,
        values: []
      }
      groups.push(dateData)
    }

    let groupedReading = dateData.values.find(x => x.t === reading.datetime)
    if (!groupedReading) {
      groupedReading = {
        t: reading.datetime
      }
      dateData.values.push(groupedReading)
    }

    const key = Object.keys(reading).filter(x => x !== 'datetime')[0]
    groupedReading[key] = reading[key]
  })
  
  return groups
}

const result = groupReadings(exampleData)
console.log(result)
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>

By using MomentJs your code will be much more readable and more easily maintained. I hope that helps, good luck!

Edit: Fixed example

Post a Comment for "Transform Json By Grouping By Date And Thereafter By Datetime In Nodejs"