PHP - 如何遍历对象数组和求和值

时间:2017-06-14 13:20:19

标签: php arrays

我有一个对象数组,如下所示:

Array
(
    [0] => stdClass Object
        (
            [ContractorID] => 7049             //<- REMOVE
            [ContractorName] => Supermarket 1  //<-REMOVE
            [SpendAmount] => 615.36            //<-SUM OF ALL ELEMENTS WHERE GroupID IS THE SAME
            [BonusAmount] => 24.61             //<-SUM OF ALL ELEMENTS WHERE GroupID IS THE SAME
            [GroupID] => 1                     //<- RETAIN
            [GroupDescription] => Supermarkets //<- RETAIN
        )

    [1] => stdClass Object
        (
            [ContractorID] => 11233
            [ContractorName] => Supermarket 2
            [SpendAmount] => 858.74
            [BonusAmount] => 34.35
            [GroupID] => 1
            [GroupDescription] => Supermarkets
        )

    [2] => stdClass Object
        (
            [ContractorID] => 19393
            [ContractorName] => Car repair shop 1 
            [SpendAmount] => 386.79
            [BonusAmount] => 15.47
            [GroupID] => 2
            [GroupDescription] => Automotive
        )

    [3] => stdClass Object
        (
            [ContractorID] => 19868
            [ContractorName] => Mike's Autos
            [SpendAmount] => 364.81
            [BonusAmount] => 14.59
            [GroupID] => 2
            [GroupDescription] => Automotive
        )

 )   

我想最终得到一个如下所示的数组:

[0] => stdClass Object
        (
            [SpendAmount] => 1474.1
            [BonusAmount] => 58.96
            [GroupID] => 1
            [GroupDescription] => Supermarkets
        )

    [1] => stdClass Object
        (
            [SpendAmount] => 751.6
            [BonusAmount] => 30.06
            [GroupID] => 2
            [GroupDescription] => Automotive
        )
)

其中BonusAmount是所有元素BonusAmount的总和,SpendAmount是所有元素SpendAmount的总和。

总结本身就很简单,但我正在努力的是如何在循环元素时保留GroupIDGroupDescription

有人能让我知道如何在语法上“保留”GroupIDGroupDescription,并根据GroupID在我的结果数组中创建一个元素吗?所有人都非常感激。

4 个答案:

答案 0 :(得分:2)

解决这个问题的一种方法是循环查看对象数组,检查您已经拥有哪些对象以及尚未使用的对象。如何执行此操作的示例如下:

        $results = [];
        foreach($objects as $object){
            if(isset($results[$object->GroupID])){
                $results[$object->GroupID]->SpendAmount += $object->SpendAmount;
                $results[$object->GroupID]->BonusAmount += $object->BonusAmount;
            }else{
                $results[$object->GroupID] = [
                    'SpendAmount' => $object->SpendAmount,
                    'BonusAmount' => $object->BonusAmount,
                    'GroupDescription' => $object->GroupDescription
                ];
            }
        }

答案 1 :(得分:2)

您可以遍历数组并对项目进行求和, live demo

 $r = [];
 foreach($array as $v)
 {
 @$r[$v->GroupID]->SpendAmount += $v->SpendAmount;
 @$r[$v->GroupID]->BonusAmount += $v->BonusAmount;
 @$r[$v->GroupID]->GroupID = $v->GroupID;
 @$r[$v->GroupID]->GroupDescription = $v->GroupDescription;
 }
 print_r(array_values($r));

答案 2 :(得分:1)

我已使用array_walk_recursive,但array_walk甚至简单foreach就足够了。

//Recreate input data from question
$in = [
        (object) [
            'ContractorID' => '7049',
            'ContractorName' => 'Supermarket 1',
            'SpendAmount' => '615.36',
            'BonusAmount' => '24.61',
            'GroupID' => '1',
            'GroupDescription' => 'Supermarkets',
        ],
        (object) [
            'ContractorID' => '11233',
            'ContractorName' => 'Supermarket 2',
            'SpendAmount' => '858.74',
            'BonusAmount' => '34.35',
            'GroupID' => '1',
            'GroupDescription' => 'Supermarkets',
        ],
        (object) [
            'ContractorID' => '19393',
            'ContractorName' => 'Car repair shop 1 ',
            'SpendAmount' => '386.79',
            'BonusAmount' => '15.47',
            'GroupID' => '2',
            'GroupDescription' => 'Automotive',
        ],
        (object) [
            'ContractorID' => '19868',
            'ContractorName' => 'Mike\'s Autos',
            'SpendAmount' => '364.81',
            'BonusAmount' => '14.59',
            'GroupID' => '2',
            'GroupDescription' => 'Automotive',
        ]
];

//For each object in the array $in, add the object details to a new array.
$return = [];
array_walk_recursive($in, function($a) use (&$return) {
    $found = false;
    //Does this group exist in the array? If so - add spendamount and bonus amount to group.
    foreach($return as $group) {
        if($group->GroupID== $a->GroupID) {
            $found = true;

            $group->SpendAmount += $a->SpendAmount;
            $group->BonusAmount += $a->BonusAmount;

            break;
        }
    }

    //Group not found - create it.
    if(!$found) {
        $return[] = (object) [
            'SpendAmount' => $a->SpendAmount,
            'BonusAmount' => $a->BonusAmount,
            'GroupID' => $a->GroupID,
            'GroupDescription' => $a->GroupDescription,
        ];
    }
});

var_dump($return);
/*
array (size=2)
  0 => 
    object(stdClass)[6]
      public 'SpendAmount' => float 1474.1
      public 'BonusAmount' => float 58.96
      public 'GroupID' => string '1' (length=1)
      public 'GroupDescription' => string 'Supermarkets' (length=12)
  1 => 
    object(stdClass)[7]
      public 'SpendAmount' => float 751.6
      public 'BonusAmount' => float 30.06
      public 'GroupID' => string '2' (length=1)
      public 'GroupDescription' => string 'Automotive' (length=10)
*/

答案 3 :(得分:0)

这不是一个数组而是一个对象,因此它们的处理方式不同http://php.net/manual/en/language.types.object.php

您可以$obj->field_name

访问对象

你可以循环遍历这个对象

$result = [];
foreach($object as $obj) {
   $result[] = $obj->field1 + $ojb->field2;
}