javascript - 如何从系列中提取连续天数?
问题描述
我正在尝试编写一个递归函数来查找数组中连续天的开始和结束索引。
这是我的示例输入:
var input = [
'2018-06-11',
'2018-06-12',
'2018-06-15',
'2018-06-16',
'2018-06-17',
'2018-06-19'
];
我希望我的输出是:
var expectedOutput = [{
start: '2018-06-11',
end: '2018-06-12'
},
{
start: '2018-06-15',
end: '2018-06-17'
},
{
start: '2018-06-19',
end: '2018-06-19'
}
];
所以我想找到连续几天的开始/结束日期。
个人的日子应该是自己的。
我写了一个算法,但它在第一天就停止了。
function extractConsecutiveDays(input, index) {
if (input == null || input.length === 0) {
return;
}
if(isConsecutiveDay(input[index], input[index + 1])) {
return extractConsecutiveDays(input, index + 1);
}
var obj = {
start: input[0],
end: input[index]
};
input.splice(0, index);
return obj;
}
解决方案
我在上面问过你为什么想要一个递归解决方案(这个问题并不适合它),听起来你对非递归解决方案持开放态度。如果是这样,请参阅评论:
function findConsecutive(array) {
var result = [];
var current = null;
// Loop through building up each result, starting a new entry each
// time we find a non-consecutive day
array.forEach(function(entry) {
// If this is the first pass or this entry isn't consecutive with
// the last, start a new entry
if (!current || !areConsecutive(current.end, entry)) {
result.push(current = {
start: entry,
end: entry
});
} else {
// It's consecutive, just extend the last one
current.end = entry;
}
});
return result;
}
现场示例:
var input = [
'2018-06-11',
'2018-06-12',
'2018-06-15',
'2018-06-16',
'2018-06-17',
'2018-06-19'
];
// I *THINK* this `areConsecutive` implementation is reliable across DST
// boundaries (http://jsfiddle.net/em8xqtc2/3/), but be sure to test...
var ONE_DAY_IN_MILLIS = 86400000;
function toDateUTC(str) {
var parts = str.split("-");
return Date.UTC(+parts[0], +parts[1] - 1, +parts[2]);
}
function areConsecutive(a, b) {
return toDateUTC(b) - toDateUTC(a) == ONE_DAY_IN_MILLIS;
}
function findConsecutive(array) {
var result = [];
var current = null;
// Loop through building up each result, starting a new entry each
// time we find a non-consecutive day
array.forEach(function(entry) {
// If this is the first pass or this entry isn't consecutive with
// the last, start a new entry
if (!current || !areConsecutive(current.end, entry)) {
result.push(current = {
start: entry,
end: entry
});
} else {
// It's consecutive, just extend the last one
current.end = entry;
}
});
return result;
}
var expectedOutput = findConsecutive(input);
console.log(expectedOutput);
.as-console-wrapper {
max-height: 100% !important;
}
我在那里只使用了 ES5 级别的功能,因为您出现在您的解决方案中。但是,如果您使用 ES2015+,则不会有太大变化:
const input = [
'2018-06-11',
'2018-06-12',
'2018-06-15',
'2018-06-16',
'2018-06-17',
'2018-06-19'
];
// I *THINK* this `areConsecutive` implementation is reliable across DST
// boundaries (http://jsfiddle.net/em8xqtc2/3/), but be sure to test...
const ONE_DAY_IN_MILLIS = 86400000;
function toDateUTC(str) {
const [year, month, day] = str.split("-");
return Date.UTC(+year, +month - 1, +day);
}
function areConsecutive(a, b) {
return toDateUTC(b) - toDateUTC(a) == ONE_DAY_IN_MILLIS;
}
function findConsecutive(array) {
const result = [];
let current = null;
// Loop through building up each result, starting a new entry each
// time we find a non-consecutive day
for (const entry of array) {
// If this is the first pass or this entry isn't consecutive with
// the last, start a new entry
if (!current || !areConsecutive(current.end, entry)) {
result.push(current = {
start: entry,
end: entry
});
} else {
// It's consecutive, just extend the last one
current.end = entry;
}
}
return result;
}
const expectedOutput = findConsecutive(input);
console.log(expectedOutput);
.as-console-wrapper {
max-height: 100% !important;
}
推荐阅读
- arrays - 两个条件的索引匹配,然后排除以前返回的值
- javascript - 经纬度变量提取问题
- telnet - 可以通过 SSH Telnet 登录到电子邮件服务器吗?我收到身份验证错误
- python - 你可以使用 pandas groupby 对行进行分组,通过对列值求和来确定吗?
- android-studio - Android Studio:选择了组件,但属性编辑器显示“未选择组件”
- php - 当我尝试使用 symfony 序列化程序序列化对象时,我得到了一些 emty 字段(created_at 和 updated_at)?
- html - Div 没有被放置在彼此旁边
- arrays - 如何在 Swift 的 TableView 中使用页脚在部分下上传标签?
- sql - 如何更改 postgres 中数组的默认标识符 {..}?
- javascript - “被 CORS 策略阻止”,但存在标头