3

我有一个数组,例如看起来像这样:

$cases = array(23, 18, 5, 8, 10, 16);

我想要的输出是一个运行总计:

23, 41, 46, 54, 64, 80

一些有助于澄清的信息:此数组当前正在填充折线图,我的目标是尝试添加一条线来显示每天的累积进度。(数据来自数据库,所以我不能只更改原始数组)

4

8 回答 8

10

最简单的方法,复杂度为 O(n):

$original = array(23, 18, 5, 8, 10, 16);

$total = array();
$runningSum = 0;

foreach ($original as $number) {
    $runningSum += $number;
    $total[] = $runningSum;
}

var_dump($total);
于 2013-06-03T17:03:46.593 回答
8

array_map. 它遍历数组,增加实际总和并返回它。

$actual_sum = 0;
$running_total = array_map(function ($entry) use (&$actual_sum) { return $actual_sum += $entry; }, $cases);
于 2013-06-03T17:00:59.230 回答
4

使用生成器(5.5 的新功能):

function getRunningTotal(array $array) {
    $generator = function(array $array) {
        $total = 0;
        foreach ($array as $key => $value) {
            $total += $value;
            yield $key => $total;
        }
    };
    return iterator_to_array($generator($array));
}

如果您想将结果保留为迭代器,只需$generator($array)直接返回...

它的工作方式是引擎在内部创建一个生成器(其作用类似于迭代器),它“返回”任何产生的内容。因此,通过将我们自己的运行总计保持在函数中,我们可以将其“输出”回给调用者。很直接...

于 2013-06-03T17:36:02.393 回答
4

介绍RunningTotalIterator解决方案,主要是为了补充其他答案:

class RunningTotalIterator extends ArrayIterator
{
    private $sum;

    public function rewind()
    {
        parent::rewind();
        $this->sum = $this->valid() ? parent::current() : 0;
    }

    public function current()
    {
        return $this->sum;
    }

    public function next()
    {
        parent::next();
        if ($this->valid()) {
            $this->sum += parent::current();
        }
    }
}

$result = iterator_to_array(new RunningTotalIterator(array(23, 18, 5, 8, 10, 16)));
print_r($result);
于 2013-06-03T17:15:43.140 回答
3

array_sum()将返回添加的数组中所有数字的总和,但是如果您想要 a running total,请执行以下操作:

$total = array();
$original = array(23, 18, 5, 8, 10, 16);

foreach($original as $number)
{
    $total[] = array_sum($total)+$number;
}

print_r($total);
于 2013-06-03T16:55:23.693 回答
2

Aaaa 和另一个变体array_walk,恕我直言,这是最自然的:

$cases = array(23, 18, 5, 8, 10, 16);
$totals = array();
array_walk($cases, function($v) use (&$totals) {$totals[] = end($totals) + $v;});

看到它在行动

于 2013-06-03T17:05:52.860 回答
2
$cases = array(23, 18, 5, 8, 10, 16);
$running = array_reduce(
    $cases,
    function ($counter, $value) {
        static $summer = 0;
        $summer += $value;
        $counter[] = $summer;
        return $counter;
    },
    array()
);

var_dump($running);
于 2013-06-03T17:03:12.063 回答
1
<?
$total = array();
$points = array(23, 18, 5, 8, 10, 16);

while ($points) {
 $total[] = array_shift($points);
 echo 'point: '.array_sum($total);
}
?>
于 2013-06-03T16:59:07.310 回答