嵌套数组中的累积和PHP(递归)

时间:2016-09-12 12:58:00

标签: php arrays recursion sum

我有一个数组有几个级别(未定义或动态定义),以及一个关联键" num_products" (产品数量)。在创建数组之后,我想要另一个关联键" total",它被初始化为零,以添加所有" num_products"其中级别低于递归)。例如:

 $array = array (  "1" =>
             array ( "id" => 1, "num_products" => 3, "total" => 0,
             "sublevel" => array( "id" => 2, "num_products" => 5, "total" => 0)    );

在这里,我需要第一个总数来计算(5 + 3 = 8),第二个总计为5个。

我尝试过一个递归函数,并通过引用传递数组以修改值,但我无法实现我想要的,因为我只得到一个上层。例如:

sum_array( $array, null);

function sum_array(&$array, &$father){
   foreach($array as $key => $item){
        $array[$key]["total"] += $array[$key]["num_products"];
        $father["total"] += $array[$key]["num_products"]; 
        totales_array($array[$key]["sublevel"], $array[$key]);
   }
}

3 个答案:

答案 0 :(得分:1)

尝试使用使用递归功能 Quick Test Here

<?php   

    $array  = array (  "1" =>
                           array ( "id" => 1, "num_products" => 3, "total" => 0,
                                   "sublevel" => array( "id" => 2, "num_products" => 5, "total" => 0),
                                   "sublevel2" => array( "id" => 6, "num_products" => 7, "total" => 0),
                                   "sublevel3" => array( "id" => 15, "num_products" => 10, "total" => 0),
                           ),
                       "2" =>
                           array ( "id" => 3, "num_products" => 7, "total" => 0,
                                   "sublevel" => array( "id" => 4, "num_products" => 9, "total" => 0)    ));






    function getGroupTotal(&$array, &$total=0, $clear=0){
        if(isset($array['num_products']) && !$clear){
            $total += $array['num_products'];
            $clear = 1;
        }
        foreach($array as $key=>$data){
            if(isset($data['num_products'])){
                $total += $data['num_products'];
            }
            if(is_array($data)){
                getGroupTotal($data, $total, $clear);
            }
        }
        return $total;
    }

    function buildTotalProducts(&$array, &$total=0, &$init=[], $clear=0, &$gTotal=[]) {
        if(!$clear){
            $gTotal         = [];
            foreach ($array as $key => &$data) {
                $data['total']  = getGroupTotal($data);
                $gTotal[]       = $data['total'];
            }
            $clear = 1;
        }
        $y = 0;
        foreach($array as $key=>&$children){
            if(empty($init)){ $init = [0=>$key, 1=>$array];}

            if(is_array($children)){
                $numProd    = isset($children['num_products'])? $children['num_products']:0;
                $k          = &$children;
                if($clear==1){
                    $k['total'] = $gTotal[$y];
                    $gTotal[$y] -= $numProd;
                    $numProd = 0; $clear=2;
                }else {
                    $k['total'] = ($gTotal[$y] == 0)?$numProd : $gTotal[$y];
                    $gTotal[$y] -= $numProd;
                }
                if($init[1][$init[0]] == $array[$key]){
                    $y++;
                }
                buildTotalProducts($children, $total, $init, $clear, $gTotal);
            }
        }
        return $array;
    }


    var_dump( buildTotalProducts($array) );
    // YIELDS::     
    array (size=2)
      1 => 
        array (size=6)
          'id' => int 1
          'num_products' => int 3
          'total' => int 25
          'sublevel' => 
            array (size=3)
              'id' => int 2
              'num_products' => int 5
              'total' => int 22
          'sublevel2' => 
            array (size=3)
              'id' => int 6
              'num_products' => int 7
              'total' => int 17
          'sublevel3' => 
            array (size=3)
              'id' => int 15
              'num_products' => int 10
              'total' => int 10
      2 => 
        array (size=4)
          'id' => int 3
          'num_products' => int 7
          'total' => int 16
          'sublevel' => 
            array (size=3)
              'id' => int 4
              'num_products' => int 9
              'total' => int 9

答案 1 :(得分:-1)

这是一个 double 递归函数。

 <?php
    $array = array();
    $array2 = array();
    $array3 = array();
    $array8 = array();
    $array16 = array();
    $array16[] = array("id" => 41, "num" => 1, "total" => 0, "sublevel" => array() );
    $array24 = array();
    $array24[] = array("id" => 101, "num" => 14, "total" => 0, "sublevel" => array() );
    $array3[] = array("id" => 7, "num" => 10, "total" => 0, "sublevel" => array());
    $array3[] = array("id" => 31, "num" => 15, "total" => 0, "sublevel" => $array16 );
    $array2[] = array ( "id" => 3, "num" => 0, "total" => 0, "sublevel" => $array3 );
    $array2[] = array( "id" => 10 , "num" => 2, "total" => 0, "sublevel" => array( array("id" => 11, "num" => 3, "total" => 0, "sublevel" => $array24)));
    $array2[] = array("id" => 111, "num" => 5, "total" => 0, "sublevel" => array());
    $array[] = array ( "id" => 1, "num" => 2, "total" => 0, "sublevel" => $array2 );
    $array5[] = array("id" => 27, "num" => 3, "total" => 0, "sublevel" => array() );
    $array[] = array("id" => 2, "num" => 2 , "total" => 0, "sublevel" => $array5 );

    echo "<pre>"; print_r($array); echo "</pre>";
    $parent = null;
    recorrer_niveles($array, -1, $parent, $array);

    echo "<pre>"; print_r($array); echo "</pre>";

    function recorrer_niveles(&$array, $nivel, &$parent, &$original){
       $nivel++;
       foreach($array as $key => $item){
          $cantidad = $array[$key]["num"];
          $array[$key]["total"] += $cantidad;
          $cuenta = count($parent);
          for($i=$nivel;$i<$cuenta;$i++){
            unset($parent[$i]);
          } // for
          sum_original($original, $parent,  $array[$key]["num"]);
          $parent[$nivel ] = $array[$key]["id"];
          recorrer_niveles($array[$key]["sublevel"], $nivel, $parent, $original);
         } // foreach
      } // function

 function sum_original(&$original ,$parent, $cantidad){
     if(!is_array($parent)) return 0;
     foreach($original as $key => $value){
          if(isset($original[$key]["id"]) && in_array($original[$key]["id"], $parent)){
            $original[$key]["total"] += $cantidad;
         } // if
          sum_original($original[$key]["sublevel"], $parent, $cantidad);
     } // foreach
   } // function

?>

查看正在运行的代码:https://eval.in/641847

答案 2 :(得分:-2)

试试这个:

$array = array ( "1" => array ( "id" => 1, "num_products" => 3, "total" => 0, "sublevel" => array( "id" => 2, "num_products" => 5, "total" => 0) )   );

function sum_recursive($array) {
    $sum = 0;
    foreach( $array as $key=>$value ) {
        if( isset($value['sublevel']) && is_array($value['sublevel']) && count($value['sublevel'])>0 ) {
            if( isset($value['num_products']) ) {
                $sum += $value['num_products'];
            }  
            $sum += sum_recursive($value);
        } else {
            if( isset($value['num_products']) ) {
                $sum += $value['num_products'];
            }
        }
    }
    return $sum;
}

$sum = sum_recursive($array);
echo "Sum is: ".$sum;

总和是:8