Search code examples
phparraysstringsequentialhyphenation

Implode sorted number array to string with commas and merge consecutive integers into hyphenated range expressions


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"

Solution

  • 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