Prodigy_Internet Prodigy_Internet - 10 months ago 27
Javascript Question

Given an array of increasing integers: How do you return a range for every three or more consecutive integers?

Given the array (list) of integers below. I am looking to extract each integer and if three or more integers ascend consecutively; I want to replace the middle integers with a "-" to represent a range. And then lastly return values as a string.

For example, the first 7 integers from list: -6, -3, -2, -1, 0, 1, 3
Would become '-6,-3-1,3'

Because there is more than three consecutive integers from -3 to 1.

Ultimately, solution(list); should return the following string: "-6,-3-1,3-5,7-11,14,15,17-20"

In its present form it returns the following string: '-6,-3,-2,-1,0,1,3,4,5,7,8,9,10,11,14,15,17,18,19,20'
Which is simply the array converted into a string.

var list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20];
solution(list);

function solution(list) {
final = [];
range = [];
while (list.length > 0) {
take = list.splice(0,1);
range.push(take);
n = 1;
while (take+n === list[0]) {
a = list.splice(0,1);
range.push(a);
n++;
}
if (range.length >= 3) {
min = Math.min(range).toString();
max = Math.max(range).toString();
final.push(min + "-" + max);
range.length = 0;
} else if (range.length === 2) {
final.push(range[0].toString());
final.push(range[1].toString());
range.length = 0;
} else if (range.length === 1) {
final.push(range[0].toString());
range.length = 0;
}
}
return final.join(",");
}


However, I was able to get the desired result successfully in Ruby:

list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]

def solution(list)
final = []
range = []
while (list.length > 0) do
take = list.shift
range << take
n = 1
while (take+n == list[0]) do
a = list.slice!(0)
range << a
n +=1
end
if (range.length >= 3)
final << (range.min.to_s + "-" + range.max.to_s)
range = []
elsif (range.length == 2)
final << range[0]
final << range[1]
range = []
elsif (range.length == 1)
final << range[0].to_s
range = []
end
end
return final.join(",")
end


My approach in Ruby is almost identical that of my JavaScript. So, if I was wondering if someone could:

1) Explain why this approach works with Ruby, but not Javascript. Please feel free to inform me even if it is a simple syntax error on my part.

2) How I could possibly go about extracting the integers and returning the correct ranges in JavaScript?

Your help is greatly appreciated! Thanks!

Answer Source

Splice returns an array, you have to take the first item from returned array

take = list.splice(0,1)[0];

Math.min doesn't accept arrays, you can use a workaround with apply/call

Math.min.apply(null,range);

It is better to clear an array by assigning to a new array.

range = [];

I obviously prefer the functional and declarative method by @ninasholz This is just to explain why my code didn't work

var list = [-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20];
console.log(solution(list));

function solution(list) {
  final = [];
  range = [];
  while (list.length > 0) {
         //splice returns array take first item
        take = list.splice(0,1)[0];
        range.push(take); 
        n = 1;
        while (take + n === list[0]) {
              a = list.splice(0,1)[0]; 
              range.push(a);
              n++;
        }
        console.log(range);
        if (range.length >= 3) {
        //Math.min doesnt accept arrays
           min = Math.min.apply(null,range);
           max = Math.max.apply(null,range);
           final.push(min + "-" + max); 
           range = [];
        } else if (range.length === 2) {
                  final.push(range[0]);
                  final.push(range[1]);
                  range = [];
        } else if (range.length === 1) {
                  final.push(range[0]);
                  range = [];
        }
  }
  return final.join(",");
}

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download