javascript - 在momentjs中每5天查找连续日期
问题描述
我有一个日历,用户必须在其中标记日期 4 次。假设用户每天都可以标记并返回以下对象:
{
date: '2018-01-10',
dots: [{
color: 'blue',
key: 'markOne'
},
{
color: 'red',
key: 'markTwo'
},
{
color: 'black',
key: 'markThree'
},
{
color: 'yellow',
key: 'markFour'
}
]
},
{
date: '2018-02-10',
dots: [{
color: 'blue',
key: 'markOne'
},
{
color: 'red',
key: 'markTwo'
},
{
color: 'black',
key: 'markThree'
},
{
color: 'yellow',
key: 'markFour'
}
]
},
{
date: '2018-03-10',
dots: [{
color: 'blue',
key: 'markOne'
},
{
color: 'blue',
key: 'markTwo'
},
{
color: 'black',
key: 'markThree'
},
null
]
},
{...day4},
{...day5 and so on}
date
仅当连续 5 天且仅当dots
没有null
对象时,我才需要向用户显示本地通知。
因此,让我们假设用户在标记所有 4 个点2018-01-10
时开始标记(所有 4 个点),直到2018-05-10
那时应该显示本地通知(这是我已经实现的另一个逻辑)。
如果日期是连续的,但dots
数组至少有一个,null
那么它不应该发送通知。
日期应每 5 天细分一次,因此5,10,15,20,25,30
每个月都应显示不同的通知:
const notificationsEveryFiveDays = [
{day5: 'day 5 notification'},
{day10: 'day 10 notification'},
{day15: 'day15 notification'},
{day20: 'day20 notification'},
{day25: 'day25 notification'},
{day30: 'day 30 notification'}
];
到目前为止,我已经设法获取所有日期并操作对象键以返回按日期排序的数组。
export const MarkedDates = () => {
MyStorage.getItem('markedDates').then((items) => {
if (items) {
let dates = _.map(items, (val, id) => {
return {...val, date: id};
});
let sortedDates = _.sortBy(dates, 'date');
console.log(sortedDates);
}
});
};
我正在尝试使用moment-range
,但我不知道如何检查所有内容dates
是否连续dots
且不包含null
. 这是一个很难解决的问题!
解决方案
我假设您使用的是日期格式 YYYY-DD-MM。(以前没见过那个)
我的方法是首先对列表进行排序并删除任何带有空点的内容,因为它们无论如何都不算连续天。之后,我们从最短的一天开始,遍历列表并检查自上次条目以来是否已经过去了一天。当连续 5 天时,将连续天的列表添加到连续数组中。
const dates = [
{
date: '2018-02-10',
dots: [{color: 'yellow', key: 'markFour' } ]
},
{
date: '2018-01-10',
dots: [ { color: 'yellow', key: 'markFour' } ]
},
{
date: '2018-03-10',
dots: [{ color: 'black', key: 'markThree' }]
},
{
date: '2018-04-10',
dots: [{color: "blue", key: 'markOne'}]
},
{
date: '2018-05-10',
dots: [{color: "blue", key: 'markOne'}]
}]
// if there is a null then do nothing. Let get that check out of the way first
const dotsHasNull = dates.filter(pair => (pair.dots.filter(dot => dot == null) ).length).length != 0
const sortedDates = dates.map(pair => {
// convert date to moment date to use the diff function later
return {date: moment(pair.date, "YYYY-DD-MM"), dots: pair.dots}
})
.filter( (pair) => {
// filter out all days that contain null dots
// this is done to handle a case where days 1-7 are consecutive but day 1 contain a null dot, which would discard the entire range
// we want it to create a range from 2-7 instead.
return pair.dots.filter(dot => dot == null).length == 0
// Maybe you want it to discard the entire range if the range contains a dot, then move this check to after we have found the ranges.
})
.sort((a,b) => a.date.valueOf() - b.date.valueOf() ) // there are probably more efficient sorting methods:)
var consecutivePairs = [];
var currentConsecutive = [];
sortedDates.forEach(pair => {
if (currentConsecutive.length == 0) {
currentConsecutive.push(pair)
return
}
const lastConsecutivePair = currentConsecutive[currentConsecutive.length -1];
// as long as only one day has passed then keep adding to the list
if (pair.date.diff(lastConsecutivePair.date, 'days') == 1) {
currentConsecutive.push(pair)
} else {
// start with an array containing the current pair because otherwise we might skip some days
currentConsecutive = [pair];
}
if (currentConsecutive.length == 5) {
// when we have a range that is atleast 5 days long that add it to
consecutivePairs.push(currentConsecutive)
}
})
consecutivePairs.forEach(consecutive => {
// sounds like you have some specific requirements for the the notification
// so you probably have to replace this
// find every 5 days
const mark = consecutive.length - (consecutive.length % 5)
console.log("consecutive days notifications: ", "day " + mark + " notification");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
希望这能解决你的问题。
推荐阅读
- java - 连续两次检查相同的元音
- ios - 无法在 ios 上运行 ionic,错误来自 cordova 本身
- python - 神经网络的网格搜索超参数 (Keras)
- mongodb - 如何在 Spring Boot 中从 Mongodb 读取集合数据并定期发布到 kafka 主题中
- woocommerce - 删除 woocommerce 帐户详细信息中的“显示名称”字段
- python - 如何在 Python API 发布请求的“文件体”中指定文件?
- c++ - 与 C++ 上的 2019 LNK2001
- python - 当 selenium 打开 Gmail_login 时,我没有登录,当我尝试登录时,它显示以下内容:
- android - Flutter 无需手动许可即可获取用户所在的国家/地区
- xpath - 使用 appium 和 winappdriver 时 xPath 表达式无效