问题
I want to concatenate a sequence of numbers in a readable string. Consecutive numbers should be merged like this '1-4'
.
I'm able to concatenate an array with all the numbers into a complete string but I'm having trouble combining / merging consecutive numbers.
I tried comparing the previous and next values with the current one in the loop with several if
-conditions but I couldn't seem to find the right ones to make it work properly.
Examples:
if(ar[i-1] === ar[i]-1){}
if(ar[i+1] === ar[i]+1){}
My code looks like this:
var ar = [1,2,3,4,7,8,9,13,16,17];
var pages = ar[0];
var lastValue = ar[0];
for(i=1; i < ar.length; i++){
if(ar[i]-1 === lastValue){
pages = pages + ' - ' + ar[i];
}else{
pages = pages + ', ' + ar[i];
}
}
alert(pages);
Result is: 1 - 2, 3, 4, 7, 8, 9, 13, 16, 17
In the end it should look like this: 1-4, 7-9, 13, 16-17
.
EDIT: I used the first answer at @CMS' link for my Script. Looks pretty much like a shorter version of @corschdi's snippet:
var ar = [1,2,3,4,7,8,9,13,16,17];
var getRanges = function(array) {
var ranges = [], rstart, rend;
for (var i = 0; i < array.length; i++) {
rstart = array[i];
rend = rstart;
while (array[i + 1] - array[i] == 1) {
rend = array[i + 1]; // increment the index if the numbers sequential
i++;
}
ranges.push(rstart == rend ? rstart+'' : rstart + '-' + rend);
}
return ranges;
}
alert(getRanges(ar));
回答1:
This should work:
var array = [1, 2, 3, 4, 7, 8, 9, 13, 16, 17];
var ranges = [];
var index = 0;
while (index < array.length) {
var rangeStartIndex = index;
while (array[index + 1] === array[index] + 1) {
// continue until the range ends
index++;
}
if (rangeStartIndex === index) {
ranges.push(array[index]);
} else {
ranges.push(array[rangeStartIndex] + " - " + array[index]);
}
index++;
}
console.log(ranges.join(", "));
回答2:
In your code, lastValue
never changes in the loop, so you're forever comparing against the first element in the array. Also, when you do find a match, you aren't yet ready to append to the pages
result just yet--there might be more numbers to come.
One approach might be to keep a run of the current sequence of numbers (or just the first and last numbers in a run), and only append this run to the result string whenever we find a break in the sequence or hit the end of the string.
There are many ways to approach this, and I recommend checking other folks' answers at the Codewars: Range Extraction kata, which is (almost) identical to this problem.
Here's my solution:
const rangeify = a => {
const res = [];
let run = []
for (let i = 0; i < a.length; i++) {
run.push(a[i]);
if (i + 1 >= a.length || a[i+1] - a[i] > 1) {
res.push(
run.length > 1 ? `${run[0]}-${run.pop()}` : run
);
run = [];
}
}
return res.join(", ");
};
[
[1,2,3,4,7,8,9,13,16,17],
[],
[1],
[1, 2],
[1, 3],
[1, 2, 3, 8],
[1, 3, 4, 8],
[1, 1, 1, 1, 2, 3, 4, 5, 5, 16],
[-9, -8, -7, -3, -1, 0, 1, 2, 42]
].forEach(test => console.log(rangeify(test)));
来源:https://stackoverflow.com/questions/56173207/how-do-i-merge-consecutive-numbers-in-a-sorted-list-of-numbers