【问题标题】:PHP count items in a multi-dimensional arrayPHP计算多维数组中的项目
【发布时间】:2012-01-07 05:32:28
【问题描述】:

从下面的数组中可以看出,11 月 18 日出现了三个元素,11 月 22 日出现了另外两个元素。谁能告诉我如何从这个数组中分别检索 3 和 2 的计数?基本上,我想得到这样的结果:

2011 年 11 月 18 日 = 3 件商品

2011 年 11 月 22 日 = 2 项

当然,日期和不同日期的数量每次都会有所不同。这是数组:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [2011-11-18 00:00:00] => C
                )

            [1] => Array
                (
                    [2011-11-18 00:00:00] => I
                )

            [2] => Array
                (
                    [2011-11-18 00:00:00] => S
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [2011-11-22 00:00:00] => C
                )

            [1] => Array
                (
                    [2011-11-22 00:00:00] => S
                )

        )

)

【问题讨论】:

  • 您关心每个日期中的值吗? (即 C、I、S、C、S)
  • 现在我不知道,但很快我会的,所以我可能也应该尝试跟踪这些值。谢谢。
  • 所以你需要一个二维数组,日期作为键,每个日期都有一个关联值数组?
  • 是的,我的光。这听起来和我正在寻找的完全一样。

标签: php arrays multidimensional-array


【解决方案1】:

你可以使用:

count($array, COUNT_RECURSIVE);

Count number of leaves in nested array tree

【讨论】:

    【解决方案2】:

    这能满足您的需要吗?

    $dates = array(array(array("2011-11-18 00:00:00" => C), array("2011-11-18 00:00:00" => I),array
    ("2011-11-18 00:00:00" => S)),
    array(array("2011-11-22 00:00:00" => C), array("2011-11-22 00:00:00" => S)));
    
    $date_count = array();  // create an empty array
    
    foreach($dates as $date) {  // go thought the first level
        foreach($date as $d) {  // go through the second level
            $key = array_keys($d);  // get our date
            // here we increment the value at this date
            // php will see it as 0 if it has not yet been initialized
            $date_count[$key[0]]++;
        }
    }
        // show what we have
    print_r($date_count);
    

    打印:

    Array ( [2011-11-18 00:00:00] => 3 [2011-11-22 00:00:00] => 2 )
    

    注意:这假设您将始终在构建数组时获取数据,并且每个日期的格式都相同。如果您不能假设每个日期都会被格式化,这将是使用 date() 函数进行的简单转换。如果你不能假设你会得到完全像这样结构的数据,解决这个问题的最好方法可能是通过递归函数。

    【讨论】:

    • 戈德温的工作很棒。这对我来说非常有用!现在我只需要花一些时间来看看它到底在做什么。谢谢。
    • 太好了,如果您有任何问题,请告诉我。关键(没有双关语)是数组存储值,日期作为键,数字作为值。每次我们看到该日期时,该值都会增加。
    • 再次感谢。现在我明白了,终于去睡觉了!非常感谢。
    【解决方案3】:

    发布的答案对于您的代表性示例是正确的,但我想添加另一个解决方案,无论您可以创建多少嵌套数组,该解决方案都将起作用。它递归地迭代数组并计算所有子数组中的所有项。

    它返回数组中项目的总数。在第二个参数中,您可以指定一个数组 引用将包含(嵌套)数组中每个唯一键的计数。

    示例:

    <?php
    $deeply_nested = array(
                         'a' => 'x',
                         'b' => 'x',
                         'c' => 'x',
                         'd' => array(
                             'a' => 'x',
                             'b' => 'x',
                             'c' => array(
                                 'a' => 'x',
                                 'b' => 'x'
                             ),
                             'e' => 'x'
                        ) 
                    );
    
    function count_nested_array_keys(array &$a, array &$res=array()) {
        $i = 0;
        foreach ($a as $key=>$value) {
            if (is_array($value)) {
                 $i += count_nested_array_keys($value, &$res);
            }
            else {
                 if (!isset($res[$key]) $res[$key] = 0;
    
                 $res[$key]++;
                 $i++;
            }
        }
        return $i;
    }
    
    $total_item_count = count_nested_array_keys($deeply_nested, $count_per_key);
    
    echo "total count of items: ", $total_item_count, "\n";
    echo "count per key: ", print_r($count_per_key, 1), "\n";
    

    结果:

    total count of items: 8
    count per key: Array
    (
        [a] => 3
        [b] => 3
        [c] => 1
        [e] => 1
    )
    

    【讨论】:

    【解决方案4】:

    假设您的数组示例具有代表性:

    foreach ($array as $key => $value)
    {
       echo count($value) . "<br />";
    }
    

    将回显每个主数组项中的数组数量。在您的示例中,这也是每个日期的条目数。

    这当然不会检查日期本身

    【讨论】:

    • 谢谢西尔弗德拉格。这也很有效。非常简单易懂。感谢您的帮助。
    【解决方案5】:

    您可以使用array_walk_recursive() 来访问数组结构中的所有叶节点。

    类似的东西应该适合你:

    <?php
    
    $data = array(
     array(
      array('2011-11-18 00:00:00' => 'C'),
      array('2011-11-18 00:00:00' => 'I'),
      array('2011-11-18 00:00:00' => 'S')),
     array(
      array('2011-11-22 00:00:00' => 'C'),
      array('2011-11-22 00:00:00' => 'S')));
    
    function countleafkeys($value, $key, $userData)
    {
      echo "$key\n";
      if(!isset($userData[$key])) {
        $userData[$key] = 1;
      } else {
        $userData[$key]++;
      }
    }
    
    $result = array();
    array_walk_recursive($data, 'countleafkeys', &$result);
    
    print_r($result);
    

    输出:

    2011-11-18 00:00:00
    2011-11-18 00:00:00
    2011-11-18 00:00:00
    2011-11-22 00:00:00
    2011-11-22 00:00:00
    Array
    (
        [2011-11-18 00:00:00] => 3
        [2011-11-22 00:00:00] => 2
    )
    

    【讨论】:

    • +1 用于使用array_walk_recursive(),顺便说一句:这种技术是不是某种en.wikipedia.org/wiki/Lambda_lifting??
    • @MGA 谢谢!老实说,Lambda 提升对我来说是一个新术语,所以你可能是一个更好的判断者(现在)关于它是否是。感谢您的睡前阅读!
    【解决方案6】:

    对于您特定的$array 结构,我认为最精简的方法是使用foreach,然后从每个值中获取日期值和count()

    $dateCounts = array();
    foreach($array as $date)
    {
        $dateCounts[key($date[0])] = count($date);
    }
    var_dump($dateCounts);
    

    有了你的$array,这给出了:

    array(2) {
      ["2011-11-18 00:00:00"]=> int(3)
      ["2011-11-22 00:00:00"]=> int(2)
    }
    

    如果您正在寻找更通用的方法,您可以使用RecursiveArrayIteratorRecursiveIteratorIterator 遍历所有叶子键/值元素,然后只计算键:

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
    $keyCounts = array();
    foreach ($it as $key => $value)
    {
        isset($keyCounts[$key]) ? $keyCounts[$key]++ : $keyCounts[$key] = 1; 
    } 
    var_dump($keyCounts);
    

    希望这会有所帮助。

    【讨论】:

      【解决方案7】:
      <?php
      $count0=count($array[0], COUNT_RECURSIVE)-count($array[0]);
      $count1=count($array[1], COUNT_RECURSIVE)-count($array[1]);
      

      【讨论】:

      • 这是一个非常好的二维数组计数解决方案。要获得总数:max( 0, count($array, COUNT_RECURSIVE) - count($array) )。 (max(0, ...) 如果数组为空)(编辑:我知道这是 100% 的主题,但值得一提的是 imo)
      【解决方案8】:

      这是我的递归变体:

      $arr = array(
          '0' => array(
              '0' => array('2011-11-18 00:00:00' => 'C'),
              '1' => array('2011-11-18 00:00:00' => 'I'),
              '2' => array('2011-11-18 00:00:00' => 'S')
          ),
          '1' => array(
              '0' => array('2011-11-22 00:00:00' => 'C'),
              '1' => array('2011-11-22 00:00:00' => 'S')
          ),
          '2' => array(
              '0' => array(
                  '0' => array('2011-11-22 00:00:00' => 'D')
              )
          )
      );
      
      function count_values($array, &$result = array(), $counter = 0)
      {
          foreach ($array as $key => $data)
          {
              if (is_array($data))
              {
                  count_values($data, $result, $counter);
              }
              else
              {
                  array_key_exists($key, $result) ? $result[$key]++ : $result[$key] = 1;
              }
          }
      
          return $result;
      }
      
      print_r(count_values($arr));
      

      这将返回:

      Array ( [2011-11-18 00:00:00] => 3 [2011-11-22 00:00:00] => 3 )
      

      【讨论】:

        【解决方案9】:

        如果您想计算一维和二维的项目,您可以尝试:

        echo 'Size of unidimensional is: '.count($celda).'<br/>';
        
        echo 'Size of bidimensional is: '.count($celda[0]).'<br/>';
        

        【讨论】:

          猜你喜欢
          • 2011-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-13
          • 2021-12-10
          • 2013-10-26
          • 1970-01-01
          • 2016-08-31
          相关资源
          最近更新 更多