Is there a simple way to take a list of numbers which can be in the range 1 - 15. And put a dash in place of consecutive numbers.
So that for example if you had the following numbers:
1 2 3 5 6 7 10 12
It would output
1 - 3, 5 - 7, 10, 12
Is there a simple way to take a list of numbers which can be in the range 1 - 15. And put a dash in place of consecutive numbers.
So that for example if you had the following numbers:
1 2 3 5 6 7 10 12
It would output
1 - 3, 5 - 7, 10, 12
<?php
$n = array (1, 2, 3, 5, 6, 7, 10, 12);
sort ($n); // If necessary.
$i = 0;
while ($i < count ($n))
{
if ($i != 0)
print (", ");
$rangestart = $i;
print ($n [$i++]);
while ($i < count ($n) && $n [$i] == $n [$i - 1] + 1)
$i++;
if ($i > $rangestart + 1)
print (" - " . $n [$i - 1]);
}
$n = array (1, 2, 4, 5, 7, 8, 10, 11, 12, 13, 14, 16, 17);
$lastindex = count($n)-1;
foreach($n as $k => $i)
{
if($k == 0) echo $i;
elseif($i != $n[$k-1]+1) echo ', ' . $i;
elseif($k == $lastindex || $i+1 != $n[$k+1]) echo ' - ' . $i;
}
The function with explode:
function shorten( $numbers ){
$a = explode(' ',$numbers);
$lastindex = count($a)-1;
$s = '';
foreach( $a as $i => $n ){
if( $i == 0 ) $s .= $n;
else if( $a[$i-1]+1 != $n ) $s .= ', '.$n;
else if( $i == $lastindex || $n+1 != $a[$i+1] ) $s .= ' - '.$n;
}
return $s;
}
print_r(shorten('').'<br>');
print_r(shorten('1').'<br>');
print_r(shorten('1 2').'<br>');
print_r(shorten('1 3').'<br>');
print_r(shorten('1 3 4 6').'<br>');
print_r(shorten('1 3 4 6 7').'<br>');
print_r(shorten('1 2 3 4 5').'<br>');
print_r(shorten('1 2 3 5 6 10 12 13').'<br>');
$lastindex
is definitely necessary, see codepad.org/4fvWpL6d Please put it back :) –
Thinner ($n+1 != $a[$i+1])
. There will not be a next item $a[$i+1]
–
Webby error_reporting(-1)
to the script, and you will get notices about nonexistent array indexes. –
Thinner Split your space-delimited values into an array then use a single loop for best time complexity / performance.
Push references into the result array which represent the start of each potential range of numbers. If contiguous values are encountered, just insert/replace the tail end of the reference value.
After populating the result array, implode them with whatever delimiter you wish.
Code: (Demo)
function hyphenate(array $numbers): string {
$result = [];
$ref = null;
foreach ($numbers as $i => $number) {
if ($ref && $number == $numbers[$i - 1] + 1) {
$ref = strtok($ref, "-") . "-$number";
} else {
unset($ref);
$ref = $number;
$result[] =& $ref;
}
}
return implode(',', $result);
}
© 2022 - 2024 — McMap. All rights reserved.