【问题标题】:Group PHP array numbers分组 PHP 数组编号
【发布时间】:2012-08-09 00:07:12
【问题描述】:

我该如何改变:

数组
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 11
    [8] => 21
    [9] => 22
    [10] => 23
    [11] => 24
)

到这里:

1-7, 11, 21-24

我在 PHP 数组中有一个这样的数字列表,我只是想让这个列表更小一点。

2000: 3 6 7 11 15 17 25 36 42 43 45
2001 年:2 3 4 5 6 9 10 11 12 13 34 37 45 46 47 48 49 50 51 52
2002:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 33 34 35 36 37 39 40 41 42 43 48 49 45 51 52
2003 年:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 451 42 473 48 4 46 50 51
2004 年:1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 21 22 23 24 25 26 27 28 29 30 31 32 33 34 36 37 38 39 40 41 42 45 44 49 5046 52
2005 年:1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 451 42 4 4 4 46 50 51 52
2006 年:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 46 42 74 4 49 50 51 52
2007 年:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 474 4 4 41 46 474 49 50 51 52

【问题讨论】:

  • 我不明白你真正想要什么,输出它?但无论如何,你尝试了什么?
  • 请提供一些示例代码,或者您迄今为止尝试过的代码。 SO 不提供免费工作。
  • 我有一个数字列表(如 1、3、4、5、6、7、8、9、10、12、13、14、15、16、18、19、20、 21, 23, 25, 27, 30, 31, 32, 33, 34, 37, 40, 41, 42, 43, 45, 47, 49, 51, 52),我只是想让它更小。而且我不知道该怎么办... $value){ if($d){ echo ", "; } 回声$值; $d = 真; } ?>

标签: php arrays numbers range grouping


【解决方案1】:

有趣的任务。

这是一个演示脚本,可以完全满足您的需求。

调整口味。

代码

<?php

$groups = array();
$active_group = 0;

$output = array();
$output_counter = 0;

$nums = array( 1, 2, 3, 4, 5, 6, 7, 11, 21, 22, 23, 24 );


foreach( $nums as $k => $num ) {

    // if this isn't the first item, and the current number
    // isn't one more than the previous one, increment the counter
    if( $k !== 0 && $nums[$k] !== $nums[$k-1]+1 )
        $active_group ++;

    // add this number to a group
    $groups[ $active_group ][] = $num;

}


// take the 1st and last of each group
foreach( $groups as $group ) {

    $first = array_shift( array_values($group) );
    $output[$output_counter][] = $first;

    $last = array_pop( array_values($group) );
    if( $first !== $last )
        $output[$output_counter][] = $last;

    $output_counter++;

}


echo '<pre>';
print_r($output);

?>

输出

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 7
        )

    [1] => Array
        (
            [0] => 11
        )

    [2] => Array
        (
            [0] => 21
            [1] => 24
        )

)

【讨论】:

    【解决方案2】:

    一个循环就可以了。您需要跟踪“先前”迭代的值和存储范围数据的“起始”值。

    代码:

    $prev = -1;                                                    // initialize out of range
    foreach ($numbers as $n) {
        if (!isset($start)) {                                      // first iteration
            $start = $n;                                           // declare $start
        } elseif ($n != $prev + 1) {                               // not consecutive
            $result[] = $start == $prev ? $prev : "$start-$prev";  // store single or ranged values
            $start = $n;                                           // update $start
        }
        $prev = $n;                                                // declare / update $prev
    }
    $result[] = $start == $prev ? $prev : $start . '-' . $prev;    // store final iteration data
    echo implode(', ', $result);                                   // comma delimit the values
    

    输出来自:$numbers = [1, 2, 3, 4, 5, 6, 7, 11, 21, 22, 23, 24]; (Demo)

    1-7, 11, 21-24
    

    输出来自:$numbers = [1, 3, 5, 6, 11, 21, 22, 23, 24, 26]; (Demo)

    1, 3, 5-6, 11, 21-24, 26
    

    【讨论】:

      【解决方案3】:

      这是一种既可以将整数数组压缩为所需的字符串格式,又可以将该字符串格式扩展回整数数组的方法。

      function compress($expanded) {
          $low = -1;
          $prevNum = -1;
          $expanded = array_unique($expanded);
          sort($expanded, SORT_NUMERIC);
          foreach($expanded as $num) {
              if($low == -1) {
                  $low = $num;
              } else if($num - $prevNum > 1) { 
                  $compact[] = ($prevNum - $low >= 1) ? sprintf("%d-%d", $low, $prevNum) : $prevNum; 
                  $low = $num;
              } 
              $prevNum = $num;
          }
          if($low != -1 ) {
              $compact[] = ($num - $low >= 1) ? sprintf("%d-%d", $low, $num) : $num; 
          }
          return implode(",", $compact);
      }
      
      public static function expand($compact) {
          $expanded = Array();
          $compact = explode(",", $compact);
          foreach($compact as $num) {
              if( is_numeric($num) ) {
                  $expanded[] = $num;
              } else {
                  list($low, $high) = explode("-", $num);
                  if( is_numeric($low) && is_numeric($high) && $low < $high) {
                      for($i = $low;$i <= $high;$i++) {
                          $expanded[] = $i;
                      }
                  }
              }
          }
          return $expanded;
      }
      

      【讨论】:

        【解决方案4】:
        //Placeholder array
        $b = array();
        
        // Slice array (where to slice)
        $s = array(11, 21);
        
        foreach ($array as $year => $a) {
            for($i = 0; $i < count($a); $i++) {
                for($ii = 0; $ii < count($s); $ii++) {
                    if($i == 0) {
                        $b[$year]['<' . $s[$ii]][] = $a[$i];
                        break;
                    } else if ( isset($a[$i+1]) && $a[$i] < $s[$ii] && $a[$i+1] >=$s[$ii]){
                        $b[$year]['<' . $s[$ii]][] = $a[$i];
                        if (isset($s[$ii+1])) {
                            $b[$year]['<' . $s[$ii+1]][] = $a[$i+1];
                        } else {
                            $b[$year]['>' . $s[$ii]][] = $a[$i+1];
                        }
                        break;
                    } else if ( !isset($s[$ii+1]) && $i == count($a) - 1) {
                        $b[$year]['>' . $s[$ii]][] = $a[$i];
                        break;
                    }
                }
            }
        }
        

        $array

        The list of numbers
        

        输出($b):

        array
          2000 => 
            array
              '<11' => 
                array
                  0 => int 3
                  1 => int 7
              '<21' => 
                array
                  0 => int 11
                  1 => int 17
              '>21' => 
                array
                  0 => int 25
                  1 => int 45
          2001 => 
            array
              '<11' => 
                array
                  0 => int 2
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 13
              '>21' => 
                array
                  0 => int 34
                  1 => int 52
          2002 => 
            array
              '<11' => 
                array
                  0 => int 1
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 20
              '>21' => 
                array
                  0 => int 21
                  1 => int 52
          2003 => 
            array
              '<11' => 
                array
                  0 => int 1
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 20
              '>21' => 
                array
                  0 => int 21
                  1 => int 51
          2004 => 
            array
              '<11' => 
                array
                  0 => int 1
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 19
              '>21' => 
                array
                  0 => int 21
                  1 => int 52
          2005 => 
            array
              '<11' => 
                array
                  0 => int 1
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 20
              '>21' => 
                array
                  0 => int 21
                  1 => int 52
          2006 => 
            array
              '<11' => 
                array
                  0 => int 1
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 20
              '>21' => 
                array
                  0 => int 21
                  1 => int 52
          2007 => 
            array
              '<11' => 
                array
                  0 => int 1
                  1 => int 10
              '<21' => 
                array
                  0 => int 11
                  1 => int 20
              '>21' => 
                array
                  0 => int 21
                  1 => int 52
        

        注意:只需更改值 (11) 和 (21) 以满足您的需要。您可以添加更多值。

        【讨论】:

        • 这是题外话,但最近在 SO 中让我烦恼的是,现在人们对答案投了反对票而没有留下任何评论,解释了为什么投反对票。
        • 我的猜测是 DV 是为了发布一个不灵活的答案。这在确定分组时不考虑数组中的元素。
        【解决方案5】:

        这是一个例子:

        $query = "SELECT '1-11' Range, COUNT(rank) rank 
            FROM promoted WHERE rank between 1 and 11 
            union all 
            SELECT '12-21' Range, COUNT(rank) rank 
            from promoted 
            where rank between 12 and 21 
            union all 
            SELECT '22-31' Range, count(rank) rank 
            from promoted 
            where rank between 22 and 31 
            union all 
            SELECT '32-40' Range, count(rank) rank 
            from promoted 
            where rank between 22 and 31 
            union all 
            SELECT rank, count(rank) FROM promoted WHERE rank = '40'";  
        

        【讨论】:

        • 假设这些来自数据库查询?
        • 这将如何对数组进行分组?你要做的就是声明一个字符串。
        猜你喜欢
        • 2017-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多