Implode sorted number array to string by commas and merge intervals

后端 未结 3 1655
不思量自难忘°
不思量自难忘° 2020-12-06 22:33

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!)

相关标签:
3条回答
  • 2020-12-06 23:01
        $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);
    
    0 讨论(0)
  • 2020-12-06 23:02

    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));
    ?>
    
    0 讨论(0)
  • 2020-12-06 23:18

    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
    
    0 讨论(0)
提交回复
热议问题