javascriptarrayssortingfilterfiltering

How can I return "1-5" if the array is a sequence like [1,2,3,4,5] and return just the number if no sequence in the array in JavaScript?


I am trying to make a program that will take a sorted array of numbers then will do like the below:

If there is a sequence, The array should push the first and last number of the sequence with a hyphen in the middle, and if not a sequence, then it just pushes the number to the output array.

For example I have sorted array [1,2,3, 5,6,7,8, 10,11, 34, 56,57].

Here (1,2,3), (5,6,7,8), (10,11), and (56,57) are sequences, and (34) is not a sequence.

Expected Output:

So the output should look like this.

["1-3", "5-8", "10-11", 34, "56-57"]

My output:

Here is my code that gives wrong output:

["1-1","1-2","1-3","5-6","5-7","5-8","10-11",34,"56-57","56-58"]

let array = [1,2,3,5,6,7,8,10,11,34,56,57];
let x = [];

for(let i = 0; i < array.length; i++){
  for(let j = 0; j < array.length; j++){
    if(array[i] + j == array[j]){
       x.push(array[i] + "-" + array[j]);
    }
    if(array[j] > array[i] + j && array[j + 1]){
      let y = array.slice(j, array.length)
      array = y;
      i, j = 0;
    }
    if(array[i] - array[i + 1] != -1 && array[i + 1] - array[i] != 1 && array[i + 1] != undefined){
      x.push(array[i]);
    }
  }
}

console.log(x);


Solution

  • If you assume that the list is sorted, we only need to traverse the list sequentially. There's no need to have double-nested loops. If you maintain sufficient states, you can determine whether you are in a group and you merely manage the start versus the last element in the group.

    To simplify things I made use of ES6 string interpolation ${start}-${last}.

    let array = [1,2,3,5,6,7,8,10,11, 34, 56,57];
    let result = [ ];
    let hasStart = false;
    let start = 0;
    let last = 0;
    for (let num of array) {
        if (!hasStart) {
            hasStart = true;
            last = start = num;
            continue;
        }
        if (num === last + 1) {
            last = num;
            continue;
        }
        result.push( start === last ? start : `${start}-${last}` );
        last = start = num;
    }
    if (hasStart) {
        result.push( start === last ? start : `${start}-${last}` );
    }
    console.log(result);