roydouek
roydouek

Reputation: 53

print the missing consecutive numbers from array as ranges

I want to show the numbers that don't show in the array in ranges, the array contains numbers ranging from 1 to 128.

for example for the array [87,89,90,91,92,93,94,95,96,97,99]

I want to print 1-86, 88, 98, 100-128

I wrote a function that works only when there are no numbers in the middle of the first unused number and the last

function PrintPorts(ports) {
  var portString = "";
  var open = true;
  let index = 1
  for (; index < 129; index++) {
    for (let j = 0; j < ports.length; j++) {
      if (index == ports[j]) {
        open = false;
        break;
      } else
        open = true;

    }
    if (open) {
      portString += index;
      break;
    }
  }
  for (; index < 129; index++) {
    for (let j = 0; j < ports.length; j++) {
      if (index == ports[j]) {
        open = false;
        break;
      } else
        open = true;
    }
    if (!open) {
      portString += "-" + (index - 1) + ",";
    }
  }
  if (index == 129 && open) portString += "-" + (index - 1);
  return portString;
}

console.log(PrintPorts([87,89,90,91,92,93,94,95,96,97,99]));

this is the result 1-86,-88,-89,-90,-91,-92,-93,-94,-95,-96,-98,-128 for the example array

when what I need is 1-86, 88, 98, 100-128

any help is appreciated

Upvotes: 4

Views: 112

Answers (4)

Y.salama
Y.salama

Reputation: 85

function PrintPorts(ports) {
	let portString = "";
	let start = 1;
  let stop = 128;
  ports.sort((a,b) => a-b)
	for (let i in ports) {
		if (start == ports[i] - 1){
    			portString += start + ","
		}
		else if(start < ports[i] - 1){
    			portString += start + "-" + String(ports[i]-1) + ",";
		}
		start = ports[i] + 1; 
	}
  if (start < stop) {
  	portString += start + "-" + String(stop);
  }
  else if (start == stop) {
  	portString += stop;
  }
  else
  	portString = portString.substring(0, portString.length-1);
	return portString;
}


console.log(PrintPorts([87,89,90,91,92,93,94,95,96,97,99]));
console.log(PrintPorts([1,3,87,89,90,91,92,93,94,95,96,97,99,128]));
console.log(PrintPorts([95,89,91,92,93,94,,87,96,97,90,99]));

Upvotes: 0

Rakesh Makluri
Rakesh Makluri

Reputation: 647

If the array is not sorted, first sort the array and then loop through the array once and find the missing ranges by comparing previous value with current value.

Below solution also contains the commented lines for missing ranges array.

You can find the working codepen here.

console.log(PrintPorts([87,89,90,91,92,93,94,95,96,97,99]))

function PrintPorts(ports) {
  const sorted = ports.sort(function (p1, p2) {return p1-p2} );
  const missingRanges = [];
  let missingRangesStr = ''
  let previous;
  sorted.forEach(function(p, index) {

    if(index == 0 && p > 1) {
      missingRangesStr += (1 + ' - ' + (p - 1)) + ', ';
      // missingRanges.push([1, p - 1]);
      previous = p;
      return;
    }
    if(index === (sorted.length - 1) && p !== 128) {
      // missingRanges.push([p + 1, 128]);
      missingRangesStr += (p  + 1 + ' - ' + 128) + ', ';
      previous = p;
      return;
    }

    if(previous && (previous + 1) !== p) {

      if((previous + 2) === p) {
        missingRangesStr += (previous + 1) + ', ';
        // missingRanges.push([previous + 1]);
      } else {
        missingRangesStr += (previous + 1) + '-' + (p - 1) + ', ' ;
        // missingRanges.push([previous + 1, p - 1]);
      }

    }
    previous = p;
  });
  return missingRangesStr.replace(/(,\s)$/, ''); 
}

Upvotes: 0

Yaroslav Lozynskyi
Yaroslav Lozynskyi

Reputation: 800

add 0 to the beginning, add 129 to the end of the array, iterate over the elements, if the difference between adjacent elements is 2 then print what's in beetween, if larger than 2 then print range.

Upvotes: 0

Barmar
Barmar

Reputation: 781310

First, simplify your code by using the includes() method to test whether an array contains an element.

Then, do it with nested loops. The outer loop looks for the start of a range. When it finds it, the inner loop looks for the end of the range. Test whether the start and end are the same to decide whether to output one number or two numbers with - between them.

And the best way to generate a comma-delimited string is by putting the results in an array, then using join() at the end to concatenate them.

function PrintPorts(ports) {
  var openPorts = [];
  for (let index = 1; index < 129; index++) {
    if (!ports.includes(index)) {
      let startPort = index;
      for (index = startPort + 1; index < 129; index++) {
        if (ports.includes(index)) {
          break;
        }
      }
      let endPort = index - 1;
      openPorts.push(startPort == endPort ? startPort : `${startPort}-${endPort}`);
    }
  }
  return openPorts.join(",");
}

console.log(PrintPorts([87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99]));
console.log(PrintPorts([1, 2, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 120, 128]));

Upvotes: 2

Related Questions