PHP按item.qty求和数组值

时间:2018-05-03 17:24:03

标签: php foreach array-column array-sum

我想知道是否有更快的方法来计算每个项目的重量,即数量。

$items = [
    [
        'qty'    => 1,
        'weight' => 1,
    ],
    [
        'qty'    => 2,
        'weight' => 1,
    ],
    [
        'qty'    => 3,
        'weight' => 1,
    ],
];

$totalWeight = 0.0;
foreach ($items as $item) {
    $totalWeight += $item['weight'] * $item['qty'];
}
echo $totalWeight . PHP_EOL;

如果我不需要qty偏移量,我可以使用

array_sum(array_column($items, 'weight'))

但是在这个例子中,这不会起作用。

任何人都有一个想法如果如何这可以更快地完成?

由于 / cottton

修改

测试脚本:

$items = [];
for ($i = 0; $i < 1000; $i++) {
    $items[] = [
        'foo'    => 1,
        'qty'    => $i,
        'bar'    => 2,
        'weight' => $i,
        'baz'    => 3,
    ];
}
$totalWeight = 0.0;


$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    $totalWeight = 0.0;
    foreach ($items as $item) {
        $totalWeight += $item['weight'] * $item['qty'];
    }
}
$elapsed = sprintf('%f', microtime(true) - $start);
echo "Elapsed: {$elapsed}\r\n";
echo "Total weight: {$totalWeight}\r\n";
// Elapsed: 0.744311
// Total weight: 332833500

3 个答案:

答案 0 :(得分:2)

使用https://www.w3schools.com/php/func_array_reduce.asp

    <?php
    $items = [
        [
            'qty'    => 1,
            'weight' => 1,
        ],
        [
            'qty'    => 2,
            'weight' => 1,
        ],
        [
            'qty'    => 3,
            'weight' => 1,
        ],
    ];


    $totalWeight = array_reduce($items, 
        function($acc, $e) { return $acc + ($e['weight'] * $e['qty']); });
    echo $totalWeight . PHP_EOL;

?>

答案 1 :(得分:2)

您可以map array_product覆盖内部数组,array_sum生成产品数组。

$totalWeight = array_sum(array_map('array_product', $items));

(如果您显示的示例在此处针对此问题进行了简化,并且内部数组包含未显示的其他字段,则此功能可能无效。)

答案 2 :(得分:0)

这是一种循环唯一权重并找到每个权重的数量之和并将其与权重相乘的方法。

在你的情况下它会产生一个循环。

$weights = array_column($items, 'weight');
$result =0;
Foreach(array_unique($weights) as $weight){
    // Finds the items with the weight 1 for example
    $weightitems = preg_grep("/". $weight . "/", $weights);
    // Sum quantity of items with the weight of 1 and multiply with weight (1).
    $result += array_sum(array_column(array_intersect_key($items, $weightitems), "qty")) * $weight;
}
Echo $result;

注意我添加了&#34; 5&#34;只是为了看到它在我的示例代码中正常工作。

https://3v4l.org/V293P


稍微优化的代码,但就我所见,仍然不比简单的循环快。
根据输入的不同,我可以慢4到4倍,但我不能比它更接近它。

$weights =array_unique(array_column($items, 'weight'));
$result =[];
Foreach($weights as $weight){
    $weightitems = array_filter($items, function ($var) use ($weight) {
        return ($var['weight'] == $weight);
    });
    $result[] = array_sum(array_column($weightitems, "qty")) * $weight;
}
Echo array_sum($result) ."\n";

https://3v4l.org/aB7d9

<小时/> 它有多准确?

这比循环更快,但在3000件物品上总共减少了1件,共计17992件 这是在误差范围内,那么这是更快。

我使用array_sum,array_column和count计算两列的sumproduct的平均值。

$count = count($items);
$weights = array_sum(array_column($items, 'weight'));
$qty = array_sum(array_column($items, 'qty'));

Echo ($qty * $weights)/$count ."\n";
// 17991 (should be 17992)

https://3v4l.org/c3CIg

我想我现在已经尝试了所有可能的解决方案。