1

I have a array of numbers. I want to print all values, but with interval if it's possible. For example:

[1,2,3,5,7,8,10]

I think you will understand what I want to get with example. For above array I want to get the following string:

"1-3, 5, 7-8, 10"

So, we have 1,2,3 in the array, then 5. The 4 is not present, so we close first interval and add to the string 1-3. Then continue, after 5 goes 7. In this case we can't create interval, therefore we just add 5. Then continue, we have 7, after 7 goes 8, after 8 goes 10, so we can create 7-8 interval only. the 10 is last so we just add it to string. In result, we have:

"1-3, 5, 7-8, 10".

I solved this task with the following:

let numbers = [1,2,3,4,7,9,12,13];

numbers.sort((a,b) => {return a - b});
let str='';
let startIndex =0, start, end;
if(numbers.length === 1) {
  str = `${numbers[0]}`;
}

for(let i=0; i< numbers.length; i++) {
  if(i === 0) {
    continue;
  }

  if(numbers[i-1] +1 !== numbers[i]) {   
    start = numbers[startIndex];
    end = numbers[i -1];
    if(start - end === 0) {
      str += `${start},`;
    }
    else {
       str += `${start} - ${end},`;
    }

    startIndex = i;

  } 

  if(i+1 === numbers.length) {
    start = numbers[startIndex];
    end = numbers[i];
    if(start - end === 0) {
      str += `${numbers[i]}`;
    } else {
           str += `${numbers[startIndex]} - ${numbers[i]}`;
    }
  }

}

console.log(str);

But, code looks very complex for understanding. Is there a better way to do this?

DEMO

4
  • What you want to achieve is not clear. Please try to elaborate more on expected result. Commented Dec 21, 2016 at 9:00
  • 6
    You should ask this on CodeReview. Commented Dec 21, 2016 at 9:00
  • @Xufox. This is not about code review only, As I said, may be better way is exist, algorithm for example. Commented Dec 21, 2016 at 9:03
  • @sAcH look at example please in the question. Commented Dec 21, 2016 at 9:05

2 Answers 2

2

You could test the items with their predecessor and move it to the right group.

var data = [1, 2, 3, 5, 7, 8, 10],
    result = data.reduce(function (r, a, i, aa) {
        if (aa[i - 1] === a - 1) {
            r[r.length - 1][1] = a;
        } else {
            r.push([a]);
        }
        return r;
    }, []).map(a => a.join('-')).join(', ');

console.log(result);

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent solution, Thank your very much, Nina.
2

Here's a function that converts a (sorted) array into an array of pairs (ranges).

let rangify = function(xs) {
    let ranges = [];
  
    for (let x of xs) {
        let last = ranges[ranges.length - 1];
  
        if (!last || x > last[1] + 1)
            ranges.push([x, x])
        else
            last[1]++;
    }
  
    return ranges;
};


let r = rangify([1,2,3,5,7,8,10,11,12,13,77,78]);
console.log(r)

It should be obvious how to get your desired output from that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.