如何使用步骤按时间对数组项进行分组
How to group item of array by time with step
我有一个这样的数组:
let arr = [
{
title: 'Some title',
start: '09:30:59',
end: '09:33:59',
},
{
title: 'Some title',
start: '09:33:59',
end: '09:35:59',
},
{
title: 'Some title',
start: '09:35:59',
end: '09:40:59',
},
{
title: 'Some title',
start: '09:30:59',
end: '09:45:59',
}
...
];
我想按某个步骤对数组进行分组,例如 10:
let result = [
{
start: '09:30:59',
end: '09:40:59',
arr: [
{
title: 'Some title',
start: '09:30:59',
end: '09:33:59',
},
{
title: 'Some title',
start: '09:33:59',
end: '09:35:59',
},
],
},
{
start: '09:40:59',
end: '09:50:59',
arr: [
{
title: 'Some title',
start: '09:35:59',
end: '09:40:59',
},
{
title: 'Some title',
start: '09:30:59',
end: '09:45:59',
}
],
},
...
];
我试过了:
let step = 10;
let diffMinutes = dayjs(arr[arr.length - 1].end).diff(arr[0].start, 'm') / step;
let newArr = [];
let result = [];
for (let t = 0; t < diffMinutes; t++) {
newArr = [];
for (let i = 0; i < arr.length; i++) {
if (dayjs(arr[i].start).isBetween(arr[0].start, dayjs(arr[0].start).add(step, 'm').format('YYYY-MM-DD HH:mm'))) {
newArr.push(state.events[i]);
}
}
result.push(
{
...
arr: newArr
}
)
}
我添加了 dayjs
条件,检查事件开始时间是否进入特定时间段。
我认为它可以比我做的更容易。
结果 shout 是按时间分组的数组,词干为 10。
所以在 else 语句中我应该使用最后一个数组结果的最后一项。
但它仅适用于第一次迭代,我知道接下来该怎么做。
请帮帮我。
您可以取时间的前四个字符并按此值分组。
let array = [{ title: 'Some title', start: '09:30:59', end: '09:33:59' }, { title: 'Some title', start: '09:33:59', end: '09:35:59' }, { title: 'Some title', start: '09:35:59', end: '09:40:59' }, { title: 'Some title', start: '09:30:59', end: '09:45:59' }],
group = s => s.slice(0, 4),
result = Object.values(array.reduce((r, o) => {
const key = group(o.start);
r[key] = r[key] || { start: key + '0:00', array: [] };
r[key].array.push(o);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
另一种解决方案可能是将时间值用作具有秒间隔的秒。结果按间隔分组,start
和 end
属性根据给定间隔计算。
let array = [{ title: 'Some title', start: '09:30:59', end: '09:33:59' }, { title: 'Some title', start: '09:33:59', end: '09:35:59' }, { title: 'Some title', start: '09:35:59', end: '09:40:59' }, { title: 'Some title', start: '09:30:59', end: '09:45:59' }],
seconds = time => time.split(':').reduce((a, b) => a * 60 + +b),
//interval = 600, // in seconds, here 10 minutes
interval = seconds('00:10:00'), // or by taking the seconds from a time string
group = time => Math.floor(seconds(time) / interval),
getTime = seconds => [3600, 60, 1]
.map(factor => {
var v = Math.floor(seconds / factor);
seconds %= factor;
return v.toString().padStart(2, 0);
})
.join(':'),
result = Object.values(array.reduce((r, o) => {
const key = group(o.start);
r[key] = r[key] || { start: getTime(key * interval), end: getTime((key + 1) * interval - 1), array: [] };
r[key].array.push(o);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
已解决问题example
let step = 5;
let diffMinutes = Math.round(
dayjs(arr[arr.length - 1].end).diff(arr[0].start, "m") / step
);
let result = [];
let newArr = [];
for (var i = 0; i <= diffMinutes; i++) {
newArr = [];
if (i === 0) {
for (let j = 0; j < arr.length; j++) {
if (
moment(arr[j].start).isSame(arr[0].start) ||
moment(arr[j].start).isSame(
dayjs(arr[0].start).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
) ||
moment(arr[j].start).isBetween(
arr[0].start,
dayjs(arr[0].start).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
)
) {
newArr.push(arr[j]);
}
}
} else {
let lastResult = result[result.length - 1];
let lastEllArr = lastResult[lastResult.length - 1];
console.log("i" + i, lastEllArr.start);
for (let j = 0; j < arr.length; j++) {
if (
moment(arr[j].start).isSame(
dayjs(lastEllArr.end).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
) ||
moment(arr[j].start).isBetween(
lastEllArr.end,
dayjs(lastEllArr.end).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
)
) {
newArr.push(arr[j]);
}
}
}
if (newArr.length !== 0) {
result.push(newArr);
}
}
如果有人建议改进代码,我将不胜感激
我有一个这样的数组:
let arr = [
{
title: 'Some title',
start: '09:30:59',
end: '09:33:59',
},
{
title: 'Some title',
start: '09:33:59',
end: '09:35:59',
},
{
title: 'Some title',
start: '09:35:59',
end: '09:40:59',
},
{
title: 'Some title',
start: '09:30:59',
end: '09:45:59',
}
...
];
我想按某个步骤对数组进行分组,例如 10:
let result = [
{
start: '09:30:59',
end: '09:40:59',
arr: [
{
title: 'Some title',
start: '09:30:59',
end: '09:33:59',
},
{
title: 'Some title',
start: '09:33:59',
end: '09:35:59',
},
],
},
{
start: '09:40:59',
end: '09:50:59',
arr: [
{
title: 'Some title',
start: '09:35:59',
end: '09:40:59',
},
{
title: 'Some title',
start: '09:30:59',
end: '09:45:59',
}
],
},
...
];
我试过了:
let step = 10;
let diffMinutes = dayjs(arr[arr.length - 1].end).diff(arr[0].start, 'm') / step;
let newArr = [];
let result = [];
for (let t = 0; t < diffMinutes; t++) {
newArr = [];
for (let i = 0; i < arr.length; i++) {
if (dayjs(arr[i].start).isBetween(arr[0].start, dayjs(arr[0].start).add(step, 'm').format('YYYY-MM-DD HH:mm'))) {
newArr.push(state.events[i]);
}
}
result.push(
{
...
arr: newArr
}
)
}
我添加了 dayjs
条件,检查事件开始时间是否进入特定时间段。
我认为它可以比我做的更容易。
结果 shout 是按时间分组的数组,词干为 10。
所以在 else 语句中我应该使用最后一个数组结果的最后一项。
但它仅适用于第一次迭代,我知道接下来该怎么做。
请帮帮我。
您可以取时间的前四个字符并按此值分组。
let array = [{ title: 'Some title', start: '09:30:59', end: '09:33:59' }, { title: 'Some title', start: '09:33:59', end: '09:35:59' }, { title: 'Some title', start: '09:35:59', end: '09:40:59' }, { title: 'Some title', start: '09:30:59', end: '09:45:59' }],
group = s => s.slice(0, 4),
result = Object.values(array.reduce((r, o) => {
const key = group(o.start);
r[key] = r[key] || { start: key + '0:00', array: [] };
r[key].array.push(o);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
另一种解决方案可能是将时间值用作具有秒间隔的秒。结果按间隔分组,start
和 end
属性根据给定间隔计算。
let array = [{ title: 'Some title', start: '09:30:59', end: '09:33:59' }, { title: 'Some title', start: '09:33:59', end: '09:35:59' }, { title: 'Some title', start: '09:35:59', end: '09:40:59' }, { title: 'Some title', start: '09:30:59', end: '09:45:59' }],
seconds = time => time.split(':').reduce((a, b) => a * 60 + +b),
//interval = 600, // in seconds, here 10 minutes
interval = seconds('00:10:00'), // or by taking the seconds from a time string
group = time => Math.floor(seconds(time) / interval),
getTime = seconds => [3600, 60, 1]
.map(factor => {
var v = Math.floor(seconds / factor);
seconds %= factor;
return v.toString().padStart(2, 0);
})
.join(':'),
result = Object.values(array.reduce((r, o) => {
const key = group(o.start);
r[key] = r[key] || { start: getTime(key * interval), end: getTime((key + 1) * interval - 1), array: [] };
r[key].array.push(o);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
已解决问题example
let step = 5;
let diffMinutes = Math.round(
dayjs(arr[arr.length - 1].end).diff(arr[0].start, "m") / step
);
let result = [];
let newArr = [];
for (var i = 0; i <= diffMinutes; i++) {
newArr = [];
if (i === 0) {
for (let j = 0; j < arr.length; j++) {
if (
moment(arr[j].start).isSame(arr[0].start) ||
moment(arr[j].start).isSame(
dayjs(arr[0].start).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
) ||
moment(arr[j].start).isBetween(
arr[0].start,
dayjs(arr[0].start).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
)
) {
newArr.push(arr[j]);
}
}
} else {
let lastResult = result[result.length - 1];
let lastEllArr = lastResult[lastResult.length - 1];
console.log("i" + i, lastEllArr.start);
for (let j = 0; j < arr.length; j++) {
if (
moment(arr[j].start).isSame(
dayjs(lastEllArr.end).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
) ||
moment(arr[j].start).isBetween(
lastEllArr.end,
dayjs(lastEllArr.end).add(step, "m").format("YYYY-MM-DD HH:mm:ss")
)
) {
newArr.push(arr[j]);
}
}
}
if (newArr.length !== 0) {
result.push(newArr);
}
}
如果有人建议改进代码,我将不胜感激