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!)
Examples:
array(1,2,3,6,8,9) => "1-3,6,8-9"
array(2,4,5,6,8,10) => "2,4-6,8,10"
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!)
Examples:
array(1,2,3,6,8,9) => "1-3,6,8-9"
array(2,4,5,6,8,10) => "2,4-6,8,10"
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
$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));
?>
Similar to the answer @ Reduce array of month names by creating hyphenated expressions from consecutive months
Push a number as a reference into the result array if the array is empty or the number does not immediately follow the previous number.
When consecutive numbers are encountered, rebuild the reference string by preserving the leading number and appending a new hyphen and the new number.
One loop and one conditional expression is all that is needed.
Code: (Demo)
function hyphenatedRanges(array $numbers): string
{
$result = [];
foreach ($numbers as $i => $number) {
if (isset($ref) && $number === $numbers[$i - 1] + 1) {
$ref = strtok($ref, "-") . "-$number";
} else {
unset($ref);
$ref = $number;
$result[] = &$ref;
}
}
return implode(',', $result);
}
echo hyphenatedRanges([1, 2, 3, 6, 8, 9]) . "\n"; // "1-3,6,8-9"
echo hyphenatedRanges([2, 4, 5, 6, 8, 10]); // "2,4-6,8,10"