【问题标题】:Elegant way to aggregate multi-dimensional array by index key通过索引键聚合多维数组的优雅方式
【发布时间】:2010-05-05 19:04:14
【问题描述】:

我怎样才能递归地找到一个看起来像这样的数组的所有子元素的总值?

 [0] => Array
    (
        [value] => ? // 8590.25 + 200.5 + 22.4
        [children] => Array
            (
                [0] => Array
                    (
                        [value] => ? // 8590.25 + 200.5
                        [children] => Array
                            (
                                [0] => Array
                                    (
                                        [value] => 8590.25 // leaf node
                                    )
                                [1] => Array
                                    (
                                        [value] => 200.05 // leaf node
                                    )
                            )

                    )
                [1] => Array
                    (
                        [value] => 22.4 // leaf node
                    )
             )
    )

【问题讨论】:

  • 您能否提供var_export 或纯PHP 版本的数组:它是否有实际的value 和children 项目,或者它们只是说明如何计算值?跨度>
  • 实际数据是一个包含树的 RecursiveIterator 对象——我只是使用关联数组来简化“如何递归聚合多维数据类型中的叶节点”的问题。所以具体实现对我来说并不重要——我只需要一个算法。

标签: php recursion multidimensional-array hierarchical-data


【解决方案1】:

在这种情况下,我会使用类而不是数组。这样,您可以拥有一个 getValue () 方法(或使用魔法来使用 __get 定义 value 属性),它可以根据需要对子值求和。如果您保证事情不会在某个点之后发生变化,则可以缓存这些子总和以避免重复计算。也许是这样的?

class DataStructure
{
  private $children = array ();
  private $value = 0;

  public function __construct ($value = 0)
  {
    $this->value = $value;
  }

  public function getValue ()
  {
    $total = $this->value;
    foreach ($this->children as $child)
    {
      $total += $child->getValue ();
    }
    return $total;
  }

  public function addChild (DataStructure $child)
  {
    $this->children[] = $child;
  }
}

【讨论】:

  • 有趣的是,这棵树是一个 RecursiveIterator(DataStructure 类实现 RecursiveIterator),我正在尝试在扩展该 DataStructure 的类中进行聚合(AggregateDatastructure 类扩展 DataStructure)。我已经得再看看这些东西.. :-P
  • 酷。然后我敢打赌,一旦你理清了实现的细节,你只需添加一两个方法就可以实现这一点。这个想法是这样的:与其编写一段代码来遍历所有深度,不如问每个孩子你被问过的同样的事情,他们会转身问他们的孩子......
【解决方案2】:

这将为您提供叶节点值的总和:

$sum = 0;
array_walk_recursive($arr, create_function('$v, $k, $sum', '$sum[0] += $v;'), array(&$sum));

使用匿名函数等效(PHP 5.3+):

$sum = 0;
array_walk_recursive($arr, function ($v) use (&$sum) { $sum += $v; });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 2020-01-02
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    相关资源
    最近更新 更多