【发布时间】:2020-11-20 18:19:54
【问题描述】:
我正在使用 .splice() 从包含时间戳的对象数组中删除对象,具体取决于 userDates 是否包含匹配的时间戳或对象时间戳之前或之后 45 分钟范围内的时间戳.本质上是使用 userDates 数组日期值删除所有具有重叠日期值的对象。
当您运行此代码时,您会注意到一些对象被删除,但其他对象没有。
JSFiddle:https://jsfiddle.net/jb2t3Lr9/1/ 和重现问题的代码:
let userDates = ["2020-11-20T22:00:00.000Z","2020-11-20T23:00:00.000Z","2020-11-21T00:00:00.000Z","2020-11-21T01:00:00.000Z","2020-11-22T02:15:00.000Z","2020-11-22T03:15:00.000Z","2020-11-22T01:00:00.000Z","2020-11-22T00:00:00.000Z","2020-11-21T23:00:00.000Z","2020-12-13T22:00:00.000Z","2020-12-14T22:00:00.000Z","2020-12-15T22:00:00.000Z","2020-12-16T22:00:00.000Z","2020-12-13T23:00:00.000Z","2020-12-14T23:00:00.000Z","2020-11-21T20:00:00.000Z","2020-11-22T20:00:00.000Z","2020-11-22T19:00:00.000Z","2020-11-21T19:00:00.000Z"];
let datesToUpdate = [
{ sessionInterval: 50, dateTime: '2020-11-22T20:00:00.000Z' },
{ sessionInterval: 50, dateTime: '2020-11-21T20:00:00.000Z' },
{ sessionInterval: 50, dateTime: '2020-11-21T19:00:00.000Z' },
{ sessionInterval: 50, dateTime: '2020-11-22T19:00:00.000Z' },
{ sessionInterval: 50, dateTime: '2020-11-22T17:30:00.000Z' },
{ sessionInterval: 50, dateTime: '2020-11-21T17:00:00.000Z' }
];
function removeOverlappingDates(userDates, datesToUpdate) {
const FIFTEEN_MINUTES = 15 * 60 * 1000; // milliseconds
datesToUpdate.forEach((toUpdate, index) => {
userDates.forEach((date) => {
let dateInMS = new Date("" + date).valueOf();
const fifteenBefore = dateInMS - FIFTEEN_MINUTES;
const thirtyBefore = dateInMS - FIFTEEN_MINUTES * 2;
const fortyFiveBefore = dateInMS - FIFTEEN_MINUTES * 3;
const fifteenAfter = dateInMS + FIFTEEN_MINUTES;
const thirtyAfter = dateInMS + FIFTEEN_MINUTES * 2;
const fortyFiveAfter = dateInMS + FIFTEEN_MINUTES * 3;
let toUpdateInMS = new Date("" + toUpdate.dateTime).valueOf();
if (
toUpdateInMS == fifteenBefore ||
toUpdateInMS == thirtyBefore ||
toUpdateInMS == fortyFiveBefore ||
toUpdateInMS == fifteenAfter ||
toUpdateInMS == thirtyAfter ||
toUpdateInMS == fortyFiveAfter ||
toUpdateInMS == dateInMS
) {
datesToUpdate.splice(index, 1);
}
});
});
return datesToUpdate;
}
console.log("datesToUpdate 1", datesToUpdate);
datesToUpdate = removeOverlappingDates(userDates, datesToUpdate);
console.log("datesToUpdate 2", datesToUpdate);
对我来说更奇怪的是,如果我只是将日期时间值数组相互比较(与对象数组包含的日期时间值相同),那么所有内容都会被正确删除。小提琴:https://jsfiddle.net/rc1mvzLq/
【问题讨论】:
-
不要修改你当前正在迭代的集合(或者至少只有当你真的知道你在做什么时)->
datesToUpate.forEach((toUpdate, index) => { /*...*/ datesToUpdate.splice(index, 1) });如果删除索引1处的元素,索引2处的元素会发生什么情况? -
在最后一个元素的开始处使用
Array.prototype.filter()或for循环并转到第一个 -
@Andreas,哦,索引值改变了!所以这就是为什么我什至尝试将索引一起收集到另一个数组中并在循环之后运行另一个循环来拼接 datesToUpdate,它也不起作用......啊。好的,我再试一次。
-
您不是在检查代码中的范围,而是检查提到的范围内的确切值。这是有目的的还是应该实际上是
if (toUpdateInMS >= fortyFiveBefore || toUpdateInMS <= fortyFiveAfter)?同样如前所述,您应该复制数组并遍历数组的副本,因为一旦进行第一次拼接,数组索引就会移动,但如果它已经在索引 2 上,则循环将永远不会回到索引 1。但是那仍然不会工作,因为您依赖于旧索引,但需要找到新元素的索引。 -
*更正:
if (toUpdateInMS >= fortyFiveBefore && toUpdateInMS <= fortyFiveAfter)
标签: javascript node.js datetime