通过在NodeJS中按日期分组,然后按日期时间分组来转换JSON [英] Transform JSON by grouping by date and thereafter by datetime in NodeJS
问题描述
我有一个IoT读取的JSON,如下所示:
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",
"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
}
]
我想通过仅按日期对数据进行分组来转换JSON模式,并且在其内部将同一日期时间的所有读数(苯,O3,NO2)显示为单个对象,如下所示:
I want to transform the JSON schema by grouping data by date only and inside it shows, into a single object, all readings (Benzene, O3, NO2) for the same datetime as follow:
[
{
"date": "2020-06-29",
"values": [
{
"Benzene": 1.9,
"t": "2020-06-29T23:59:59.000Z",
"O3": 25.6
}
]
},
{
"date": "2020-06-30",
"values": [
{
"Benzene": 0.6,
"t": "2020-06-30T00:59:59.000Z",
"NO2": 16.3
},
{
"Benzene": 5.7,
"t": "2020-06-30T01:59:59.000Z",
"NO2": 12.6,
"O3": 31.7
},
{
"Benzene": 5.5,
"t": "2020-06-30T02:59:59.000Z",
"NO2": 11.7,
"O3": 35.1
},
{
"Benzene": 5.2,
"t": "2020-06-30T03:59:59.000Z",
"NO2": 35.5,
"O3": 11.4
},
{
"Benzene": 1,
"t": "2020-06-30T04:59:59.000Z",
"NO2": 44.6,
"O3": 4.9
},
{
"Benzene": 2.1,
"t": "2020-06-30T05:59:59.000Z",
"NO2": 19.9,
"O3": 32.8
},
{
"Benzene": 4.2,
"t": "2020-06-30T06:59:59.000Z",
"NO2": 11.2,
"O3": 46.4
},
{
"Benzene": 3.4,
"t": "2020-06-30T07:59:59.000Z",
"NO2": 8.2,
"O3": 55.6
}
]
}
]
我使用以下方法可能很多余,效率也不高。
(json_from_csv_filtered包含在顶部报告的原始JSON)
I used the following approach probably quite redundant and not particularly efficient. (json_from_csv_filtered contains the original JSON reported at the top)
const data = Object.values(json_from_csv_filtered.reduce((groups, {
datetime,
...rest
}) => {
if (!groups[datetime]) {
groups[datetime] = {}
}
key = Object.keys({
...rest
})
value = Object.values({
...rest
})
groups[datetime][key[0]] = value[0];
groups[datetime]['t'] = datetime
return groups;
}, []));
const result = data.reduce((groups, readings) => {
const date = readings.t.split('T')[0];
if (!groups[date]) {
groups[date] = [];
}
groups[date].push(readings);
return groups;
}, {})
const groupArrays = Object.keys(result).map((date) => {
return {
date,
values: result[date]
};
});
console.log(JSON.stringify(groupArrays, null, 2));
有人可以建议更好的方法吗?
而且, t键代表读数的日期时间,我不知道为什么,它总是出现在苯键之后,我想应该是相反的。
Could anyone suggest a better approach? Moreover, 't' key, representing readings' datetime, I don't know why, appear always after 'Benzene' key, I would like it should be the opposite.
谢谢。
推荐答案
您可以将两个哈希表用于长日期和短日期,并获取短日期的值。
You could take two hash table for long and short date and get the short date's values.
要获得更深入的了解,您可以看一下 r
对象,该对象包含两个 long $ c属性$ c>和
short
。
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: 3
t: "2020-06-29T23:59:59.000Z",
Benzene: 1.9,
O3: 25.6
},
"2020-06-30T00:59:59.000Z": { // id: 4
t: "2020-06-30T00:59:59.000Z",
Benzene: 0.6,
NO2: 16.3
},
"2020-06-30T01:59:59.000Z": { // id: 5
t: "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
包含用于收集完整时间戳的属性的对象,并将该对象推送到对应的 short
集合中,该集合按 short 日期。
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.
在 short
属性中,所有对象都是结果的最后一部分设置分组日期数据并按时间戳分组时间 long 日期。
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; }
这篇关于通过在NodeJS中按日期分组,然后按日期时间分组来转换JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!