Why is splicing an array in JavaScript removing the last few elements?

I’m currently working on an array function that converts subarrays of consecutive numbers into strings denoting that range of numbers — for example, this array…

[1, 2, 3, 6, 8, 10, 11, 12, 15, 18]

…would become this array:

["1-3", 6, 8, "10-12", 15, 18]

I’ve been able to develop a function that mostly works, but I’ve encountered a weird error where all the elements past the final range of numbers spliced into the array are completely deleted. For example, the test array above actually becomes this:

["1-3", 6, 8, "10-12"]

This is the code I’ve written so far. It’s not super pretty yet, but as I mentioned above, it gets the job done right up until the very end:

let testArray = [1, 2, 3, 6, 8, 10, 11, 12, 15, 18];

for (i = 0; i < testArray.length; i++) {
  let consecutives = [];
  consecutives.push(testArray[i]);
  let j = i + 1;
  while (j < testArray.length) {
    if (testArray[j] == (testArray[j - 1] + 1)) {
      consecutives.push(testArray[j]);
      j++;
    } else {
      break;
    }
  }
  if (consecutives.length > 2) {
    let range = String(testArray[i]) + "-" + String(testArray[j - 1]);
    console.log(testArray);
    console.log(testArray[i]);
    console.log(testArray[j]);
    testArray.splice(i, j, range);
  }
}

console.log(testArray);

These are the console logs output by that code:

Array(10) [ 1, 2, 3, 6, 8, 10, 11, 12, 15, 18 ]
1
6
Array(8) [ "1-3", 6, 8, 10, 11, 12, 15, 18 ]
10
15
Array(4) [ "1-3", 6, 8, "10-12" ]

I initially figured this was caused by a mix-up with array indexes, but playing around with the index-1s hasn’t fixed the problem yet. Has anyone else ever had a similar issue with JavaScript’s splicing, and if so, how were you able to get it working?

Answer

When you do:

testArray.splice(i, j, range);

You are forgetting that j is the right limit index of the array that you want to erase, so you need to subtract i that is the left limit:

testArray.splice(i, j - i, range);

let testArray = [1, 2, 3, 6, 8, 10, 11, 12, 15, 18];

for (i = 0; i < testArray.length; i++) {
  let consecutives = [];
  consecutives.push(testArray[i]);
  let j = i + 1;
  while (j < testArray.length) {
    if (testArray[j] == (testArray[j - 1] + 1)) {
      consecutives.push(testArray[j]);
      j++;
    } else {
      break;
    }
  }
  if (consecutives.length > 2) {  // doesn´t it should be > 1 ??
    let range = String(testArray[i]) + "-" + String(testArray[j - 1]);
    console.log(testArray);
    console.log(testArray[i]);
    console.log(testArray[j]);
    testArray.splice(i, j - i, range);
  }
}

console.log(testArray);