如何按天、1 小时、6 小时、8 小时、周、月和年对日期数组和求和值进行分组?
How to group array of dates and sum value by day, 1hour, 6hours, 8hours, week, month, and year?
我有日期数组,我想按年、月、周、日、6 小时、8 小时和 1 小时以及求和值对日期进行分组。例如,我有以下数组:
const data = [
{ x: "2021-10-17T14:38:45.540Z", y: 2 },
{ x: "2021-09-16T14:36:46.540Z", y: 1 },
{ x: "2021-01-04T14:35:46.540Z", y: 2 },
{ x: "2021-01-01T14:30:46.540Z", y: 1 },
{ x: "2020-02-01T06:28:47.520Z", y: 12 },
{ x: "2020-02-01T07:28:47.520Z", y: 12 },
// ...
{ x: "2019-04-13T10:19:20.034Z", y: 20 },
// ...
{ x: "2018-01-01T09:09:19.134Z", y: 4 },
{ x: "2017-01-01T12:09:19.034Z", y: 11 },
{ x: "2016-01-02T12:10:20.034Z", y: 24 },
// ...
]
这是我尝试使用 momentjs 和 lodash Group array of object by date
我得到这个结果的那一年,2018 年和 2016 年的问题没有显示:
[
{
"color": "Blue",
"value": 6,
"label": "2021"
},
{
"color": "Blue",
"value": 24,
"label": "2020"
},
{
"color": "Blue",
"value": 1212,
"label": "2019"
},
{
"color": "Blue",
"value": 11,
"label": "2017"
}
]
年预期产量:
[
{
"color": "Blue",
"value": 6,
"label": "2021"
},
{
"color": "Blue",
"value": 24,
"label": "2020"
},
{
"color": "Blue",
"value": 1212,
"label": "2019"
},
{
"color": "Blue",
"value": 10,
"label": "2018"
},
{
"color": "Blue",
"value": 11,
"label": "2017"
},
{
"color": "Blue",
"value": 48,
"label": "2016"
}
]
这可以通过使用 reduce 的标准 'group-by' 来实现,这里使用 Object.values()
.
累积到一个对象并返回一个数组
我已经声明了一个简单的 get_date_parts
帮助程序来解析 ISO 日期字符串,这对于分组来说应该足够了,但如果需要,您可以使用 Date 对象来处理更复杂的标签格式。
这是年份分组,该模式可以适应所有其他分组,但您需要做一些算术来确定小时范围。
const data = [{ x: '2021-10-17T14:38:45.540Z', y: 2 }, { x: '2021-09-16T14:36:46.540Z', y: 1 }, { x: '2021-01-04T14:35:46.540Z', y: 2 }, { x: '2021-01-01T14:30:46.540Z', y: 1 }, { x: '2020-02-01T06:28:47.520Z', y: 12 }, { x: '2020-02-01T07:28:47.520Z', y: 12 }, { x: '2019-04-13T10:19:20.034Z', y: 20 }, { x: '2018-01-01T09:09:19.134Z', y: 4 }, { x: '2017-01-01T12:09:19.034Z', y: 11 }, { x: '2016-01-02T12:10:20.034Z', y: 24 },];
function get_date_parts(iso_string) {
const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
return { year, month, day, hr, min, sec };
}
function group_by_year(arr) {
return Object.values(
arr.reduce((a, { x: date_string, y: value }) => {
const { year } = get_date_parts(date_string);
(a[year] ??= { color: 'Blue?', value: 0, label: year }).value += value;
return a;
}, {}),
);
}
const grouped_by_year = group_by_year(data).sort((a, b) => +b.label - +a.label);
console.log(grouped_by_year);
或按月,还显示了 logical nullish assignment (??=) 的替代方案,用于初始分配给 a[key]
。
const data = [{ x: '2021-10-17T14:38:45.540Z', y: 2 }, { x: '2021-09-16T14:36:46.540Z', y: 1 }, { x: '2021-01-04T14:35:46.540Z', y: 2 }, { x: '2021-01-01T14:30:46.540Z', y: 1 }, { x: '2020-02-01T06:28:47.520Z', y: 12 }, { x: '2020-02-01T07:28:47.520Z', y: 12 }, { x: '2019-04-13T10:19:20.034Z', y: 20 }, { x: '2018-01-01T09:09:19.134Z', y: 4 }, { x: '2017-01-01T12:09:19.034Z', y: 11 }, { x: '2016-01-02T12:10:20.034Z', y: 24 },];
function get_date_parts(iso_string) {
const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
return { year, month, day, hr, min, sec };
}
function group_by_month(arr) {
return Object.values(
arr.reduce((a, { x: date_string, y: value }) => {
const { year, month } = get_date_parts(date_string);
const key = `${year}/${month}`;
// using logical nullish assignment
//(a[key] ??= { color: 'Blue?', value: 0, label: key }).value += value;
// or written out long hand
if (a[key] === undefined) {
a[key] = { color: 'Blue?', value: 0, label: key };
}
a[key].value += value;
return a;
}, {}),
);
}
const grouped_by_month = group_by_month(data).sort((a, b) => b.label.localeCompare(a.label));
console.log(grouped_by_month);
对于没有直接用日期表示的分组,您可以使用一些简单的算法。
function get_date_parts(iso_string) {
const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
return { year, month, day, hr, min, sec };
}
const date_string = '2020-02-07T07:28:47.520Z';
const { year, month, day, hr } = get_date_parts(date_string);
// week in the month
const week = Math.floor((parseInt(day, 10) - 1) / 7);
const week_label = `${year}/${month} - week ${week + 1}`;
console.log({ week_label, week });
// hour range
const range_size = 8;
const range = Math.floor(parseInt(hr, 10) / range_size);
// range times
const range_start = `${(range * range_size).toString().padStart(2, '0')}:00`;
const range_end = `${(range * range_size + range_size).toString().padStart(2, '0')}:00`;
const range_label = `${day}/${month}/${year} ${range_start}-${range_end}`;
console.log({ range_label, range });
我有日期数组,我想按年、月、周、日、6 小时、8 小时和 1 小时以及求和值对日期进行分组。例如,我有以下数组:
const data = [
{ x: "2021-10-17T14:38:45.540Z", y: 2 },
{ x: "2021-09-16T14:36:46.540Z", y: 1 },
{ x: "2021-01-04T14:35:46.540Z", y: 2 },
{ x: "2021-01-01T14:30:46.540Z", y: 1 },
{ x: "2020-02-01T06:28:47.520Z", y: 12 },
{ x: "2020-02-01T07:28:47.520Z", y: 12 },
// ...
{ x: "2019-04-13T10:19:20.034Z", y: 20 },
// ...
{ x: "2018-01-01T09:09:19.134Z", y: 4 },
{ x: "2017-01-01T12:09:19.034Z", y: 11 },
{ x: "2016-01-02T12:10:20.034Z", y: 24 },
// ...
]
这是我尝试使用 momentjs 和 lodash Group array of object by date
我得到这个结果的那一年,2018 年和 2016 年的问题没有显示:
[
{
"color": "Blue",
"value": 6,
"label": "2021"
},
{
"color": "Blue",
"value": 24,
"label": "2020"
},
{
"color": "Blue",
"value": 1212,
"label": "2019"
},
{
"color": "Blue",
"value": 11,
"label": "2017"
}
]
年预期产量:
[
{
"color": "Blue",
"value": 6,
"label": "2021"
},
{
"color": "Blue",
"value": 24,
"label": "2020"
},
{
"color": "Blue",
"value": 1212,
"label": "2019"
},
{
"color": "Blue",
"value": 10,
"label": "2018"
},
{
"color": "Blue",
"value": 11,
"label": "2017"
},
{
"color": "Blue",
"value": 48,
"label": "2016"
}
]
这可以通过使用 reduce 的标准 'group-by' 来实现,这里使用 Object.values()
.
我已经声明了一个简单的 get_date_parts
帮助程序来解析 ISO 日期字符串,这对于分组来说应该足够了,但如果需要,您可以使用 Date 对象来处理更复杂的标签格式。
这是年份分组,该模式可以适应所有其他分组,但您需要做一些算术来确定小时范围。
const data = [{ x: '2021-10-17T14:38:45.540Z', y: 2 }, { x: '2021-09-16T14:36:46.540Z', y: 1 }, { x: '2021-01-04T14:35:46.540Z', y: 2 }, { x: '2021-01-01T14:30:46.540Z', y: 1 }, { x: '2020-02-01T06:28:47.520Z', y: 12 }, { x: '2020-02-01T07:28:47.520Z', y: 12 }, { x: '2019-04-13T10:19:20.034Z', y: 20 }, { x: '2018-01-01T09:09:19.134Z', y: 4 }, { x: '2017-01-01T12:09:19.034Z', y: 11 }, { x: '2016-01-02T12:10:20.034Z', y: 24 },];
function get_date_parts(iso_string) {
const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
return { year, month, day, hr, min, sec };
}
function group_by_year(arr) {
return Object.values(
arr.reduce((a, { x: date_string, y: value }) => {
const { year } = get_date_parts(date_string);
(a[year] ??= { color: 'Blue?', value: 0, label: year }).value += value;
return a;
}, {}),
);
}
const grouped_by_year = group_by_year(data).sort((a, b) => +b.label - +a.label);
console.log(grouped_by_year);
或按月,还显示了 logical nullish assignment (??=) 的替代方案,用于初始分配给 a[key]
。
const data = [{ x: '2021-10-17T14:38:45.540Z', y: 2 }, { x: '2021-09-16T14:36:46.540Z', y: 1 }, { x: '2021-01-04T14:35:46.540Z', y: 2 }, { x: '2021-01-01T14:30:46.540Z', y: 1 }, { x: '2020-02-01T06:28:47.520Z', y: 12 }, { x: '2020-02-01T07:28:47.520Z', y: 12 }, { x: '2019-04-13T10:19:20.034Z', y: 20 }, { x: '2018-01-01T09:09:19.134Z', y: 4 }, { x: '2017-01-01T12:09:19.034Z', y: 11 }, { x: '2016-01-02T12:10:20.034Z', y: 24 },];
function get_date_parts(iso_string) {
const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
return { year, month, day, hr, min, sec };
}
function group_by_month(arr) {
return Object.values(
arr.reduce((a, { x: date_string, y: value }) => {
const { year, month } = get_date_parts(date_string);
const key = `${year}/${month}`;
// using logical nullish assignment
//(a[key] ??= { color: 'Blue?', value: 0, label: key }).value += value;
// or written out long hand
if (a[key] === undefined) {
a[key] = { color: 'Blue?', value: 0, label: key };
}
a[key].value += value;
return a;
}, {}),
);
}
const grouped_by_month = group_by_month(data).sort((a, b) => b.label.localeCompare(a.label));
console.log(grouped_by_month);
对于没有直接用日期表示的分组,您可以使用一些简单的算法。
function get_date_parts(iso_string) {
const [year, month, day, hr, min, sec] = iso_string.split(/\D/g);
return { year, month, day, hr, min, sec };
}
const date_string = '2020-02-07T07:28:47.520Z';
const { year, month, day, hr } = get_date_parts(date_string);
// week in the month
const week = Math.floor((parseInt(day, 10) - 1) / 7);
const week_label = `${year}/${month} - week ${week + 1}`;
console.log({ week_label, week });
// hour range
const range_size = 8;
const range = Math.floor(parseInt(hr, 10) / range_size);
// range times
const range_start = `${(range * range_size).toString().padStart(2, '0')}:00`;
const range_end = `${(range * range_size + range_size).toString().padStart(2, '0')}:00`;
const range_label = `${day}/${month}/${year} ${range_start}-${range_end}`;
console.log({ range_label, range });