我正在生成一个数字列表:
[1,2,3,4,6,7,8,9,11,12,13,14,16,17,18,19]
注意缺少某些数字(在这种情况下,每5个数字)。我想将连续数字转换为范围,用短划线分隔。
在上面的例子中,我希望输出为
"1-4,6-9,11-14,16-20"
我该如何解决这个问题?
答案 0 :(得分:5)
var convertToRanges = function (str) {
// split the string at the commas and map it to an array of ints
// NOTE: if you are passing an array, skip this step
var pieces = str.split(",").map(Number)
// ranges will be an array of arrays
// each inner array will have 2 dimensions, representing the start/end
// of a range
// we want to initialize our first range to pieces[0], pieces[0],
// or (only the first element)
, ranges = [[pieces[0], pieces[0]]]
// last index we accessed (so we know which range to update)
, lastIndex = 0;
for (var i = 1; i < pieces.length; i++) {
// if the current element is 1 away from the end of whichever range
// we're currently in
if (pieces[i] - ranges[lastIndex][1] === 1) {
// update the end of that range to be this number
ranges[lastIndex][1] = pieces[i];
} else {
// otherwise, add a new range to ranges
ranges[++lastIndex] = [pieces[i], pieces[i]];
}
}
return ranges;
}
这将返回一个数组数组:
console.log(convertToRanges("1,2,3,4,6,7,8,9,11,12,13,14,16,17,18,19"));
// -> [ [1, 4], [6, 9], [11, 14], [16, 19] ]
我会留给你弄清楚如何将其转换为"1-4,6-9,11-14,16-20"
答案 1 :(得分:0)
解决方案返回完成的字符串并处理不属于范围的隔离数字
function convert(input) {
var res = [],
arr = typeof input == 'string' ? input.split(',').map(Number) : input;
while (arr.length) {
var curr = arr.shift(),
lastIncIdx = null;
if (arr.length && curr == arr[0] - 1) {
var next = arr.length ? arr.reduce(function (last, curr, idx, arr) {
if (curr == last + 1) {
lastIncIdx = idx;
return curr;
} else {
return last;
}
}) : curr;
if (next != curr) {
arr.splice(0, lastIncIdx + 1);
res.push(curr + '-' + next)
}
} else {
res.push(curr)
}
}
return res.join();
}
的 DEMO 强>