给大家提供一个小巧的ES6模块。它接受一个函数来确定我们何时必须中断序列(breakDetectorFunc参数-默认为整数序列输入的简单函数)。
注意:由于输入是抽象的,所以在处理之前没有自动排序,因此如果您的序列未排序,请在调用此模块之前进行排序。
function defaultIntDetector(a, b){
return Math.abs(b - a) > 1;
}
const sequenceToIntervals = function (valuesArray, allArraysResult, breakDetectorFunc) {
if (!breakDetectorFunc){
breakDetectorFunc = defaultIntDetector;
}
if (typeof(allArraysResult) === 'undefined'){
allArraysResult = false;
}
const intervals = [];
let from = 0, to;
if (valuesArray instanceof Array) {
const cnt = valuesArray.length;
for (let i = 0; i < cnt; i++) {
to = i;
if (i < cnt - 1) {
if (breakDetectorFunc(valuesArray[i], valuesArray[i + 1])) {
appendLastResult();
}
}
}
appendLastResult();
} else {
throw new Error("input is not an Array");
}
function appendLastResult(){
if (isFinite(from) && isFinite(to)) {
const vFrom = valuesArray[from];
const vTo = valuesArray[to];
if (from === to) {
intervals.push(
allArraysResult
? [vFrom, vTo]
: vFrom
);
} else if (Math.abs(from - to) === 1) {
if (allArraysResult) {
intervals.push([vFrom, vFrom]);
intervals.push([vTo, vTo]);
} else {
intervals.push(vFrom, vTo);
}
} else {
intervals.push([vFrom, vTo]);
}
from = to + 1;
}
}
return intervals;
};
module.exports = sequenceToIntervals;
第一个参数是输入序列排序数组,第二个参数是一个布尔标志,控制输出模式:如果为true-单个项(在间隔之外)将被返回为数组:[1,7],[9,9],[10,10],[12,20],否则单个项按照它们在输入数组中出现的顺序返回
对于您的示例输入
[2,3,4,5,10,18,19,20]
它将返回:
sequenceToIntervals([2,3,4,5,10,18,19,20], true) // [[2,5], [10,10], [18,20]]
sequenceToIntervals([2,3,4,5,10,18,19,20], false) // [[2,5], 10, [18,20]]
sequenceToIntervals([2,3,4,5,10,18,19,20]) // [[2,5], 10, [18,20]]
sequence-to-range
https://www.npmjs.com/package/sequence-to-range - Ram Prasad Agarwal