【问题标题】:Applying array_map recursively (array_walk_recursive?)递归应用array_map(array_walk_recursive?)
【发布时间】:2014-04-07 21:28:23
【问题描述】:

我有一个关联数组,我使用以下代码从 ODBC 查询创建:

        while ($row=odbc_fetch_array($oexec)) {
        if(empty($group[$row['gmm']])) {
            $group[$row['gmm']] = array();
        }
        if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']])) {
            $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']] = array();
        }
        if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']])) {
            $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']] = array();
        }
        if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']])) {
            $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']] = array();
        }
        if(empty($group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']])) {
            $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']] = array();
        }
        $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_ty_yest_sales'] = $row['total_ty_yest_sales'];
        $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['total_wo_dotcom_ty_yest_sales'] = $row['total_wo_dotcom_ty_yest_sales'];
        $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['east_ty_yest_sales'] = $row['east_ty_yest_sales'];
        $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['central_ty_yest_sales'] = $row['central_ty_yest_sales'];
        $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['west_ty_yest_sales'] = $row['west_ty_yest_sales'];
        $group[$row['gmm']][$row['acctg_dept_nbr'] . " - " . $row['acctg_dept_desc']][$row['dept_catg_grp_desc']][$row['dept_category_desc']][$row['dept_subcatg_desc']]['dotcom_ty_yest_sales'] = $row['dotcom_ty_yest_sales'];

    }

这给了我一个数组,其中:

$myArray = Array(GMM => Array(acctg_dept_nbr => Array(dept_category_desc => Array(dept_subcatg_desc => Array(value1,value2,value3)))))

我想对每个级别的值求和。所以对于每个 acctg_dept_nbr[dept_category_desc][dept_subcatg_desc] 我想对 value1,value2,value3 求和。 GMM 级别和 dept_subcatg_desc 级别相同。对 dept_subcatg_desc 级别求和不是问题。我四处寻找并找到了如何对 dept_category_desc 级别求和,但在递归应用该方法时遇到了麻烦。

以下是将值放入表中的代码:

foreach($group as $gmm => $acctg_dept_nbrs) {
        echo "<tr class=\"header\">
        <td>" . $gmm . "</td>\n";

        foreach ($acctg_dept_nbrs as $acctg_dept_nbr => $dept_catg_grp_descs) {
                        echo "<tr class=\"header\">\n
            <td style=\"padding-left: 1em;\">" . $acctg_dept_nbr . "</td>\n";

            foreach($dept_catg_grp_descs as $dept_catg_grp_desc => $dept_category_descs) {
                echo "<tr class=\"header\">\n
                <td style=\"padding-left: 2em;\">" . $dept_catg_grp_desc . "</td>\n";
                                    //echo "<td>" . array_sum(array_walk_recursive($dept_category_descs,function($item) {return $item['total_ty_yest_sales'];})) . "</td>";
                foreach($dept_category_descs as $dept_category_desc => $dept_subcatg_descs) {
                    echo "<tr class=\"header\">\n
                    <td style=\"padding-left: 3em;\">" . $dept_category_desc . "</td>\n";
                                            echo "<td>" . array_sum(array_map(function($item) {return $item['total_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
                                            echo "<td>" . array_sum(array_map(function($item) {return $item['east_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
                                            echo "<td>" . array_sum(array_map(function($item) {return $item['central_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
                                            echo "<td>" . array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs)) . "</td>";
                    foreach($dept_subcatg_descs as $dept_subcatg_desc => $values) {
                                                echo "<tr>\n
                                                    <td style=\"padding-left: 4em;\">" . $dept_subcatg_desc . "</td>\n";
                                                $sum = $values['total_ty_yest_sales'];
                                                echo "<td>".$sum."</td>";
                                                $sum = $values['east_ty_yest_sales'];
                                                echo "<td>".$sum."</td>";
                                                $sum = $values['central_ty_yest_sales'];
                                                echo "<td>".$sum."</td>";
                                                $sum = $values['west_ty_yest_sales'];
                                                echo "<td>".$sum."</td>";
                    }
                }
            }
        }
    }

注释掉的行现在对我来说是个问题。这个:

array_sum(array_map(function($item) {return $item['west_ty_yest_sales'];},$dept_subcatg_descs))

在该级别上运行良好,但在更高级别上却不行。我也尝试过调整此功能无济于事:

function array_map_recursive($callback, $array) {
    foreach ($array as $key => $value) {
        if (is_array($array[$key])) {
            $array[$key] = array_map_recursive($callback, $array[$key]);
        }
        else {
            $array[$key] = call_user_func($callback, $array[$key]);
        }
    }
    return $array;
}

我怎样才能使这项工作,无论级别如何,它都会挖掘并总结数组中该部分的值?

【问题讨论】:

  • 您确定您的回调正在返回一个值?这个递归函数似乎没有什么问题。
  • 如果我使用:array_sum(array_map_recursive(function($item) {return $item['total_ty_yest_sales'];},$dept_category_descs)) 我得到一个非法的字符串偏移错误。回调在这里起作用:array_sum(array_map(function($item) {return $item['total_ty_yest_sales'];},$dept_subcatg_descs))
  • 您将匿名 / lambda 函数作为字符串传递给回调参数,因此 call_user_func 不会像这样工作,因为它会尝试调用名为 function($item){...} 的函数,您应该单独定义回调, 并传入它的名字。
  • 谢谢,我想我刚刚明白了。让我们看看我能不能弄清楚...
  • 我认为您可以通过将call_user_func($callback, $array[$key]); 替换为简单的$callback($array[$key]); 来做到这一点

标签: php arrays recursion


【解决方案1】:
function array_map_recursive($callback, $array)
{
  $func = function ($item) use (&$func, &$callback) {
    return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item);
  };

  return array_map($func, $array);
}

【讨论】:

    【解决方案2】:

    如果我们将多个数组添加到函数中,可能会有点困难。但是只有一个,完全没有问题。

          function array_map_recursive(&$arr, $fn) {
                return array_map(function($item) use($fn){
                    return is_array($item) ? array_map_recursive($item, $fn) : $fn($item);
                }, $arr);
            }
    
          $array = array_map_recursive($array, function($item){
                //TODO logic here
          });
    
    

    【讨论】:

      【解决方案3】:

      filter_var 基本上可以用来完成这个

      function array_map_recursive(callable $func, array $array) {
          return filter_var($array, FILTER_CALLBACK, ['options' => $func]);
      }
      

      有一个很大的缺点...... 回调将接收作为字符串的值。 叶子不能是物体

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 1970-01-01
        • 2019-03-23
        • 2014-08-24
        • 1970-01-01
        • 2015-02-20
        • 1970-01-01
        相关资源
        最近更新 更多