-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
61 lines (57 loc) · 1.78 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const sortNumber = (a, b) => a - b;
const numberPattern = '[1-9]\\d{0,5}';
const singleNumberRegExp = new RegExp(`^${numberPattern}$`);
const numberListRegExp = new RegExp(`^\\s*(${numberPattern})(?:\\s*-\\s*(${numberPattern}))?(?:,\\s*|\\s+|$)`);
module.exports = {
parse(s) {
const numbers = [];
let m;
while ((m = s.match(numberListRegExp))) {
s = s.slice(m[0].length);
let n = +m[1];
const end = m[2] == null ? n : +m[2];
if (n > end) {
throw new Error(`Invalid range "${n}-${end}"`);
}
while (n <= end) {
if (numbers.indexOf(n) === -1) {
numbers.push(n);
}
n++;
}
}
if (s) {
throw new Error(`Invalid number list "${s}"`);
}
return numbers.sort(sortNumber);
},
stringify(numbers) {
numbers = numbers.map(function (n) {
if (!singleNumberRegExp.test(n)) {
throw new Error(`Invalid number "${n}"`);
}
return +n;
});
const list = [];
let currentItem = '';
let prevN = 0;
numbers.sort(sortNumber);
numbers.push(0);
numbers.forEach(function (n) {
if (!prevN || !n || n > prevN + 1) {
if (currentItem) {
if (currentItem !== prevN.toString()) {
currentItem += '-' + prevN;
}
list.push(currentItem);
currentItem = '';
}
if (!currentItem) {
currentItem = n.toString();
}
}
prevN = n;
});
return list.join(', ');
},
};