我有一系列日期,我想转换为更漂亮的字符串格式。相应的日期名称必须显示为范围。
以下是一个例子:
// 0 is Sunday, 6 is Saturday
days = [0,1,2,4,5];
// Should be ["Sunday-Tuesday", "Thursday-Friday"]
days = [0,1,3,5,6]
// Should be ["Friday-Monday", "Wednesday"]
// note that this wraps around!!
我已经尝试了有些成功,但它没有包装。它也是丑陋,imo。
let result = [];
let build = "";
let previous = -10;
let days = [0,1,3,5,6];
for(let i=0;i < days.length; i++) {
let d = parseInt(days[i]);
if (d !== previous+1 && i > 0) {
build = build.slice(1).split(",");
if (build.length == 1)
build = build[0];
else if (build.length > 0) {
build = build[0] + "-" + build[build.length-1];
}
result.push(build);
build = "";
}
build = build + "," + getDayName(d);
if (i === days.length-1) {
build = build.slice(1).split(",");
if (build.length == 1)
build = build[0];
else if (build.length > 0) {
build = build[0] + "-" + build[build.length-1];
}
result.push(build);
}
previous = d;
}
这只会打印出Array [ "Sunday-Monday", "Wednesday", "Friday-Saturday" ]
。
我怎样才能让日子环绕?有没有更清洁的方法呢?
答案 0 :(得分:0)
如果将问题分成以下三个步骤,它将变得简单。
[[0, 1], [3], [5, 6]]
[[5, 6, 0, 1], [3]]
['Friday-Monday', 'Wednesday']
const convert = dayNumbers => {
// 1. chunking into consecutive elements, such that [[0, 1], [3], [5, 6]]
let chunks = []
dayNumbers.forEach(num => {
if (chunks.length === 0) chunks.unshift([num])
else if (chunks[0][0] === num - 1) chunks[0].unshift(num)
else chunks.unshift([num])
})
chunks = chunks.map(c => c.reverse()).reverse()
// 2. deal with wrap around, such that [[5, 6, 0, 1], [3]]
let chunksLength = chunks.length
if (chunksLength >= 2) {
let lastChunk = chunks[chunksLength - 1]
if (chunks[0][0] === 0 && lastChunk[lastChunk.length - 1] === 6) {
chunks[0] = lastChunk.concat(chunks[0])
chunks = chunks.splice(0, chunksLength - 1)
}
}
// 3. convert to string, such that ['Friday-Monday', 'Wednesday']
const dayNames = [
'Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'
]
const result = chunks.map(c => {
if (c.length === 1) return dayNames[c[0]]
else return dayNames[c[0]] + '-' + dayNames[c[c.length - 1]]
})
return result
}
console.log(convert([0, 1, 2, 4, 5])) // ['Sunday-Tuesday', 'Thursday-Friday']
console.log(convert([0, 1, 3, 5, 6])) // ['Friday-Monday', 'Wednesday']
&#13;
答案 1 :(得分:0)
我将问题分解为两个步骤:
此处附带的代码就是这样做的。 groupRanges
查看任何范围,通过它将项目分组到连续范围。这意味着它将[0, 1, 2, 4, 5]
转换为[[0, 1, 2], [4, 5]]
。
请注意,如果您提供[5, 0, 1, 2, 4]
,则会忽略4
和5
连续的事实。如果您希望将其视为连续的,则应在传递之前对其进行排序。
prettyRange
只处理以下三种情况:
groupRanges
函数使用Array.reduce
作为(我认为)一个干净的解决方案。
const days1 = [0,1,2,4,5];
const days2 = [0,1,3,5,6];
const days3 = [0,2];
const days4 = [5,1,4];
const days5 = [4];
const daysVariants = [days1, days2, days3, days4, days5];
/**
* @param {number[]} numbers - An array of numbers from 0-6
* @return {number[][]} An array of an array of numbers. Each array of numbers will be consecutive in ascending order
*/
function groupRanges(numbers) {
// Loop over numbers, building an array as we go starting with [].
return numbers.reduce((ranges, next) => {
// It's our first number so just return a single-item range
if (ranges.length <= 0) return [[next]];
const lastRange = last(ranges);
const lastNumber = last(lastRange);
// Next number is consecutive to the last number in the last-seen range, so we should add it to that range
if (next - lastNumber === 1) return [...ranges.slice(0, -1), [...lastRange, next]]
// Next number is _not_ consecutive so we add a new single-item range
return [...ranges, [next]];
}, []);
}
function last(array) {
return array[array.length - 1];
}
daysVariants
.map(groupRanges)
.forEach(i => console.log(i));
const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
function prettyRange(range) {
if (range.length === 0) return '';
if (range.length === 1) return DAYS[range[0]];
return DAYS[range[0]] + '-' + DAYS[last(range)];
}
daysVariants
.map(groupRanges)
.forEach(ranges => ranges.map(prettyRange).forEach(i => console.log(i)));
&#13;
答案 2 :(得分:0)
您可以将第一个连续日期连接到数组的末尾,这样当我们运行算法对它们进行分组时,会自动处理包装。
let names = 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'.split(',');
let i = 0;
while (days[i]+1 == days[i+1]) i++;
days = days.concat(days.splice(0, i+1));
let res = [];
let s = days[0];
for (i = 0; i < days.length-1; i++){
if ((days[i]+1)%7 != days[i+1]){
let f = days[i];
res.push(s == f ? names[s] : names[s]+'-'+names[f]);
s = days[i+1];
}
}
f = days[days.length-1];
res.push(s == f ? names[s] : names[s]+'-'+names[f]);
res.unshift(res.pop());