【问题标题】:PHP Iterate multi-dimensional arrayPHP迭代多维数组
【发布时间】:2011-12-30 05:06:02
【问题描述】:

如何遍历这个多维数组并返回正数的计数和负数的计数。答案应该是 1 肯定和 5 否定。谢谢。

Array
(
[Nov 18, 2011] => Array
    (
        [C] => Array
            (
                [C] => Array
                    (
                        [T] => -1324.388328
                    )
                [S] => Array
                    (
                        [T] => -249.976472
                    )
            )
    )
[Dec 24, 2011] => Array
    (
        [C] => Array
            (
                [C] => Array
                    (
                        [T] => -2523.107928
                    )
                [S] => Array
                    (
                        [T] => 103.533528
                    )
            )
    )
[Dec 27, 2011] => Array
    (
        [C] => Array
            (
                [C] => Array
                    (
                        [T] => -4558.837928
                    )
                [S] => Array
                    (
                        [T] => -1639.376472
                    )
            )
    )
)

【问题讨论】:

  • 不应该是5负1正吗?
  • @TomS,是的,你是对的。我解决了这个问题。

标签: php multidimensional-array iterator


【解决方案1】:

您还可以将SPLRecursiveIteratorIteratorRecursiveArrayIterator 结合使用,如下所示:

$pos = $neg = 0;
foreach( new RecursiveIteratorIterator( new RecursiveArrayIterator( $data ) ) as $item )
{
    if( !is_numeric( $item ) ) continue;

    $item < 0 ? $neg++ : $pos++;
}
var_dump( $pos, $neg );

$data 代表您的多维数组。 RecursiveIteratorIterator 默认只迭代,即所谓的叶子(没有任何子项的项目)。作为一项安全措施,我仍然结合了一个测试来检查该项目是否确实是一个数字值。

【讨论】:

    【解决方案2】:

    如果目标是计算一个未知深度的多维数组的正负数,构建一个递归函数。如果不是这样,递归函数也可以完成工作。

    function countFromMultidimentionalArray($array)
    {
        $positiveCount = 0;
    
        foreach($array as $value)
        {
            if(is_array($value))
            {
                $positiveCount += countFromMultidimentionalArray($value);
            }
            else
            {
                if($value >= 0)
                {
                    $positiveCount++;
                }
            }
        }
    
        return $positiveCount;
    }
    

    我没有对此进行测试,它只计算正数。您可以创建一个类似的函数,只计算负数,更有趣的是,找到一种方法在同一个函数中同时执行这两种方法(也许使用一个对象?)。这只是给你一个想法,因为这似乎是家庭作业,我不想破坏所有的乐趣:)

    编辑:鉴于这不是家庭作业,这里有一个更复杂的解决方案,使用数组来保存两个值。

    function countFromMultidimentionalArray($array)
    {
        $values = array();
        $values["positive"] = 0;
        $values["negative"] = 0;
    
        foreach($array as $value)
        {
            if(is_array($value))
            {
                $result += countFromMultidimentionalArray($value);
                $values["positive"] += $result["positive"];
                $values["negative"] += $result["negative"];
            }
            else
            {
                if($value >= 0)
                {
                    $values["positive"]++;
                }
                else
                {
                    $values["negative"]++;
                }
            }
        }
    
        return $values;
    }
    

    也没有测试这个。希望对您有所帮助!

    【讨论】:

    • 谢谢@TomS。尽管您的代码可能尚未经过测试,但我可以向您保证,它就像一个魅力。你让我走上了正确的道路。 p.s.这不是家庭作业,只是我试图找到一条捷径来帮助我适应学习曲线。干杯,
    • 为了完整起见,我编辑了我的答案。 @DanielAttard 请看一看。
    【解决方案3】:

    我在使用递归解决方案时遇到了一些问题,因为我也在学习 [如上所示将计数设置为零将擦除您在每次递归调用中的当前计数,并且在传递计数时我还没有解决引用/范围错误作为函数参数]。

    另外,我必须修改原始数组定义的符号才能让我的测试正常工作。
    A)我认为您的键是字符串文字,而不是变量或常量。所以我添加了 '' 包装器。如果它们是在别处定义的变量,请添加您的 '$'..
    B) 您需要用逗号分隔单个数组中的元素列表,这是我添加的
    C)技术上没有必要,但我在定义时不使用括号表示法,仅在创建后按键访问时使用。开发人员的选择,但当我稍后返回代码时,它可以帮助我确定我是(创建还是使用现有的)数组元素。
    D)不要忘记包括你的';'定义数据数组后,数组定义不会像函数或条件代码 {} 结构那样自动关闭

    诚然,这是一个比递归略逊一筹的解决方案,但它使您可以按键和按值完全访问每个元素,此时您可以根据需要报告或操作值。此方法的限制是您需要知道有多少嵌套级别(因此需要知道多少个 foreach 循环)。结果是向现有数组级别添加元素不会影响循环逻辑。

    <?php
    
      function html_pp ( $text ) // no return
      {
        // echo paragraph to browser
        echo PHP_EOL . '<p>' . Sprintf ( $text ) . '</p>' . PHP_EOL;
      }
    
      // Data array
      $data = Array
      (
        'Nov 18, 2011' => Array
        (
          'C' => Array
          (
            'C' => Array ( 'T' => -1324.388328 ), // comma
            'S' => Array ( 'T' => -249.976472  )
          )
        ), // comma
        'Dec 24, 2011' => Array
        (
          'C' => Array
          (
            'C' => Array ( 'T' => -2523.107928 ), // comma
            'S' => Array ( 'T' => 103.533528   )
          )
        ), // comma
        'Dec 27, 2011' => Array
        (
          'C' => Array
          (
            'C' => Array ( 'T' => -4558.837928 ), // comma
            'S' => Array ( 'T' => -1639.376472 )
          )  
        )
      ); // end array def
    
      // Count variables
      $positive = 0;
      $negative = 0;
    
      html_pp ( 'Data Array :' );
    
      // Loop using key => value pairs
      foreach ( $data as $i => $date ) // Iterate through date elements
      {
        foreach ( $date as $j => $c ) // Iterate through C elements
        {
          foreach ( $c as $k => $cs ) // Iterate through C/S elements
          {
            foreach ( $cs as $n => $t ) // Iterate though T elements
            {
              // echo current element nesting path and value
              html_pp ( $i . '>' . $j . '>' . $k . '>' . $n . ' = ' . $t );
              // update +- counts
              if ( $t < 0 ) { $negative += 1; }
              else          { $positive += 1; }
            }
          }
        }
      }
    
      html_pp ( 'Positive : ' . $positive );
      html_pp ( 'Negative : ' . $negative );
    
    ?>
    

    浏览器输出:

    数据数组:

    2011 年 11 月 18 日>C>C>T = -1324.388328

    2011 年 11 月 18 日>C>S>T = -249.976472

    2011 年 12 月 24 日>C>C>T = -2523.107928

    2011 年 12 月 24 日>C>S>T = 103.533528

    2011 年 12 月 27 日>C>C>T = -4558.837928

    2011 年 12 月 27 日>C>S>T = -1639.376472

    正数:1

    负数:5

    【讨论】:

    • 这是一个很好的直接解决方案。另外,我只是想通过说每次调用函数时都分配新的局部变量来解决您提到的递归问题(关于在每次调用时将计数设置为零),它们在整个执行过程中并不相同。关于通过引用传递,您可以将计数变量封装在一个对象中并传递该对象(通过引用自动传递);构建一个类并使用属性来保存计数值;或使用this method
    猜你喜欢
    • 2016-05-23
    • 2020-03-21
    • 2013-11-11
    • 2023-03-08
    • 2014-05-17
    • 1970-01-01
    • 2021-11-02
    相关资源
    最近更新 更多