I would like to implode an array, but with one difference. I would like to merge intervals with a -
sign. How can this be done? (The array is ordered!)
$oldArray=array(2,4,5,6,8,10);
$newArray=array();
foreach($oldArray as $count=>$val){
if($count==0){
//begin sequencing
$sequenceStart=$sequenceEnd=$val;
}
if($val==$sequenceEnd+1){
$sequenceEnd=$val;
continue;
}else{
if($sequenceEnd==$val){
//do nothing
continue;
}
}
//new sequence begins
//save new sequence
if($sequenceStart==$sequenceEnd){
//sequnce is a single number
$newArray[]=$sequenceEnd;
}else{
$newArray[]=$sequenceStart.'-'.$sequenceEnd;
}
//reset sequence
$sequenceStart=$sequenceEnd=$val;
}
//new sequence begins
//save new sequence
if($sequenceStart==$sequenceEnd){
//sequnce is a single number
$newArray[]=$sequenceEnd;
}else{
$newArray[]=$sequenceStart.'-'.$sequenceEnd;
}
//reset sequence
$sequenceStart=$sequenceEnd=$val;
return implode(',', $newArray);
There is no function like this, therefore you will need to create one yourself. I just created a sample function how this may look like, there are many possible solution for this (Did not try if it actually works, as I do not have a webserver in reach atm)
<?php
function implodeNumberArray($arr) {
$lastValue = NULL;
$o = "";
//For each value in array
foreach ($arr as $v) {
if(!is_null($lastValue)) {
//If the number is following, do not paste it
if(($lastValue+1) == $v) {
//Check if the - sign was already posted
if(!(stripos(strrev($o), '-') === 0)) {
// - sign not pasted, therefore paste it
$o .= "-";
}
} else {
//Check if there is a - sign at the end
if((stripos(strrev($o), '-') === 0)) {
// Has - => paste 'prevValue,value''
$o .= $lastValue . "," . $v;
} else {
//Check if there is a , sign at the end
if((stripos(strrev($o), ',') === 0)) {
// No - but , => paste 'value'
$o .= $v;
} else {
// No - and no , => paste ',value'
$o .= ",".$v;
}
}
}
} else {
$o = $v;
}
$lastValue = $v;
}
//Check if the implode has the last number set correctly
if((stripos(strrev($o), '-') === 0)) {
$o .= $lastValue;
}
return $o;
}
echo implodeNumberArray(array(1,2,3,6,8,9));
?>
This should work for you:
First for every iteration we simply append the current number of the iteration to the $result
string:
$result .= $arr[$i];
After this we check in a while loop if there exists a next element in the array(1) and it follows up the number from the current iteration(2). We do that until the condition evaluates as false:
//(1)Check if next element exists (2)Check if next element follows up the prev one
┌───────┴───────┐ ┌───────────┴────────────┐
while(isset($arr[$i+1]) && $arr[$i] + 1 == $arr[$i+1] && ++$range)
$i++;
Then we check if we have a range (e.g. 1-3
) or not. If yes then we append the dash and the end number of the range to the result string:
if($range)
$result .= "-" . $arr[$i];
At the end we also check if we are at the end of the array and don't need to append a comma anymore:
if($i+1 < $l)
$result .= ",";
Code:
<?php
$arr = array(1,2,3,6,8,9);
$result = "";
$range = 0;
for($i = 0, $l = count($arr); $i < $l; $i++){
$result .= $arr[$i];
while(isset($arr[$i+1]) && $arr[$i] + 1 == $arr[$i+1] && ++$range)
$i++;
if($range)
$result .= "-" . $arr[$i];
if($i+1 < $l)
$result .= ",";
$range = 0;
}
echo $result;
?>
output:
1-3,6,8-9