递归应用array_map(array_walk_recursive?)

10

我有一个关联数组,是通过以下代码从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;
}

如何使此代码在不考虑层级的情况下向下遍历并对数组中的该部分值进行求和?


你确定你的回调函数返回了一个值吗?这个递归函数似乎没有任何问题。 - RaggaMuffin-420
如果我使用以下代码: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))。 - user3352316
你正在将一个匿名/lambda函数作为字符串传递给回调参数,因此call_user_func不会像这样工作,因为它将尝试调用一个名为function($item){...}的函数。你应该单独定义你的回调函数,并将其名称传递进去。 - RaggaMuffin-420
谢谢,我想我刚刚明白了。让我们看看我能否弄清楚... - user3352316
我认为你可以通过将call_user_func($callback, $array[$key]);替换为简单的$callback($array[$key]);来完成它。 - RaggaMuffin-420
我已经尝试了两种方法。我仍然收到非法偏移错误。function myCallback($item,$field) { return $item[$field]; } function array_map_recursive($array,$field) { foreach ($array as $key => $value) { if (is_array($array[$key])) { $array[$key] = array_map_recursive($array[$key],$field); } else { $array[$key] = myCallback($array[$key],$field); } } return $array; } array_sum(array_map_recursive($dept_category_descs,"total_ty_yest_sales")) - user3352316
4个回答

39
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);
}

你能写一个实现吗? - ANOL GHOSH
请说明需要实现什么? - ilyar
如果我给你一个 $array => ["a"=>1,"b"=>"2"],并且我想要 a+b 的值,那么我该如何使用它?这个函数的代码行是什么? 我应该写 $sum = array_map("array_map_recursive", $array) 吗? 我想确切地知道如何使用这个函数,$callback 是什么? 或者我应该在回调函数的位置传递自己的函数? 例如: function sum($p1,$p2){ return $p1+$p2;} - ANOL GHOSH
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce https://www.php.net/manual/zh/function.array-reduce.php - ilyar

2
function array_map_recursive($callback, $array)
{
    if(is_array($callback)){
        foreach ($callback as $function){
            $array = array_map_recursive($function, $array);
        }
        return $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);
}

这样,您就可以调用传递更多函数的函数.. 例如:

$rowData = array_map_recursive(['utf8_decode', 'trim'], $rowData);

或者只调用一个简单的函数:

$rowData = array_map_recursive('trim', $rowData);


1

如果我们向函数添加多个数组,可能会有些困难。但是只有一个数组,就没有任何问题。

      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
      });


1

filter_var基本上可以用来实现这个

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

有一个很大的缺点... 回调函数将以字符串形式接收该值。 而叶子节点不能是对象


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接