如何按开始时间和结束时间对日期数组进行分组,并减去最后一个值-第一个值



我有一个按天分组的日期数组,我想按时间开始和结束对日期进行分组,并减去最后一个值-第一个值。

时间开始和结束也在一个数组中。

数据阵列:

const data = [
{ x: "2021-10-17T24:00:00.000Z", y: 52 },
{ x: "2021-10-17T22:14:00.000Z", y: 44 },
{ x: "2021-10-17T22:10:00.000Z", y: 36 },
{ x: "2021-10-17T22:00:00.000Z", y: 29 },
{ x: "2021-10-17T20:14:45.540Z", y: 24 },
{ x: "2021-10-17T20:13:45.540Z", y: 20 },
{ x: "2021-10-17T20:00:45.540Z", y: 18 },
{ x: "2021-10-17T14:38:45.540Z", y: 17 },
{ x: "2021-10-17T13:38:45.540Z", y: 15 },
{ x: "2021-09-16T14:36:46.540Z", y: 13 },
{ x: "2021-01-04T14:35:46.540Z", y: 12 },
{ x: "2021-01-01T14:30:46.540Z", y: 10 },
{ x: "2020-02-01T06:28:47.520Z", y: 7 },
{ x: "2020-02-01T07:28:47.520Z", y: 6 },
{ x: "2019-04-13T10:19:20.034Z", y: 5 },
{ x: "2018-01-01T09:09:19.134Z", y: 4 },
{ x: "2017-01-01T12:09:19.034Z", y: 3 },
{ x: "2016-01-02T12:10:20.034Z", y: 2 },
{ x: "2016-01-02T11:10:20.034Z", y: 1 }
];

时间起始和结束数组:

const configurations = [
{
label: "C1",
startTime: { hr: "06", min: "00" },
endTime: { hr: "22", min: "00" }
},
{
label: "C2",
startTime: { hr: "22", min: "00" },
endTime: { hr: "24", min: "00" }
}
];

按天分组的数据:

[
{
"value": 37, // 52 -15 (last value - first value)
"label": "2021/10/17",
// (I want to group this data by time start and end)
"data": [
{
"x": "2021-10-17T13:38:45.540Z",
"y": 15
},
{
"x": "2021-10-17T14:38:45.540Z",
"y": 17
},
{
"x": "2021-10-17T20:00:45.540Z",
"y": 18
},
{
"x": "2021-10-17T20:13:45.540Z",
"y": 20
},
{
"x": "2021-10-17T20:14:45.540Z",
"y": 24
},
{
"x": "2021-10-17T22:00:00.000Z",
"y": 29
},
{
"x": "2021-10-17T22:10:00.000Z",
"y": 36
},
{
"x": "2021-10-17T22:14:00.000Z",
"y": 44
},
{
"x": "2021-10-17T24:00:00.000Z",
"y": 52
}
]
},
//...
]

预期输出:

[
{
"value": 37, // 52 -15 (last value - first value)
"label": "2021/10/17",
"data": [
{
value: 14, // 29-15 =14
label: "C1"
},
{
value: 23, // 52-29 = 23
label: "C2"
}
]
},
// ...
]

这就是我尝试的按时间开始和结束分组数据的方法。

我没有在您的所有脚本中遵循逻辑。我只想在下面评论一下:

parseInt(item.startTime.hr, 10) * 60

parseInt是多余的,因为乘法将强制字符串为数字。

我已将输入数据修改为使用日期对象而不是时间戳,并且所有计算都使用UTC。

以下内容首先生成日期分组数据,然后对配置数据进行处理。如果一个组中只有一天,则值为0,因为这是第一个也是最后一个条目。如果没有适合配置类别的天数,则该值为空,因此不会添加到结果数据中。

其中一个forEach循环可以转换为reduce,但有时forEach在逻辑上更容易理解。:-)

希望这些评论是足够的,请询问您是否需要澄清。

let data = [
{ x: new Date('2021-10-17T23:59:59.999Z'), y: 52 },
{ x: new Date('2021-10-17T22:14:00.000Z'), y: 44 },
{ x: new Date('2021-10-17T22:10:00.000Z'), y: 36 },
{ x: new Date('2021-10-17T22:00:00.000Z'), y: 29 },
{ x: new Date('2021-10-17T20:14:45.540Z'), y: 24 },
{ x: new Date('2021-10-17T20:13:45.540Z'), y: 20 },
{ x: new Date('2021-10-17T20:00:45.540Z'), y: 18 },
{ x: new Date('2021-10-17T14:38:45.540Z'), y: 17 },
{ x: new Date('2021-10-17T13:38:45.540Z'), y: 15 },
{ x: new Date('2021-09-16T14:36:46.540Z'), y: 13 },
{ x: new Date('2021-01-04T14:35:46.540Z'), y: 12 },
{ x: new Date('2021-01-01T14:30:46.540Z'), y: 10 },
{ x: new Date('2020-02-01T06:28:47.520Z'), y: 7 },
{ x: new Date('2020-02-01T07:28:47.520Z'), y: 6 },
{ x: new Date('2019-04-13T10:19:20.034Z'), y: 5 },
{ x: new Date('2018-01-01T09:09:19.134Z'), y: 4 },
{ x: new Date('2017-01-01T12:09:19.034Z'), y: 3 },
{ x: new Date('2016-01-02T12:10:20.034Z'), y: 2 },
{ x: new Date('2016-01-02T11:10:20.034Z'), y: 1 }
];
let configurations = [
{
label: "C1",
startTime: { hr: "06", min: "00" },
endTime: { hr: "22", min: "00" }
},
{
label: "C2",
startTime: { hr: "22", min: "00" },
endTime: { hr: "24", min: "00" }
}
];
function groupByDay(data) {
// Used in reduce
let currentDate, group;
// Group by day
let dayGroups = data.reduce((acc, item) => {
// Get the date
let date = item.x.toISOString().substring(0,10);
// If a new date, start a new group
if (date != currentDate) {
currentDate = date;
group = {value:'', label:date, data:[]};
acc.push(group);
}
// Add item to start of data, update value
group.data.unshift(item);
group.value = group.data[group.data.length - 1].y - group.data[0].y;

return acc;
}, []);

return dayGroups;
}
function processConfigs(dayGroups, config) {
// Convert {hr, min} to ms
let configTimeToMs = ({hr, min}) => hr*3.6e6 + min*6e4;
// Get ms since start of UTC day
let dateTimeToMs = (date) => date % 8.64e7;
// For each dayGroup, collect data for each config
return dayGroups.reduce((acc, dayGroup) => {
// Create a new configGroup
let configGroup = {value:dayGroup.value, label:dayGroup.label, data:[]};
acc.push(configGroup);

// For each config, add data to configGroup.data
config.forEach(config => {
let configStart = configTimeToMs(config.startTime);
let configEnd = configTimeToMs(config.endTime);
let configObj = {value: '', label: config.label};
// Add data for each day
let groupFirstValue = null;
dayGroup.data.forEach(day => {
let dayMs = dateTimeToMs(day.x);
// If falls in config time range
if (dayMs >=configStart && dayMs <= configEnd) {
// If groupFirstValue not already set
if (!groupFirstValue) {
groupFirstValue = day.y;
}
// Update value
configObj.value = day.y - groupFirstValue;
}
});
// If value is empty, there are no days for this config so don't add
if (configObj.value !== '') {
configGroup.data.push(configObj);
}
});
return acc;
}, []);
}
let dayGroups = groupByDay(data);
// console.log(dayGroups);
console.log(processConfigs(dayGroups, configurations));

相关内容

最新更新