0

This is my array of objects in php:

Array( [0]=>
  Array (
    [added_time] => 2018-12-09 14:00:00+00 
    [id] => 123
    [places] => 
      [{
        "place_id" : 1,
        "total" : 5, 
        "empty" : 0,
        "weight" : 68000,
        "persons" : 
         [{
           "person_id" : 2,
           "person_name" : "ABC",
           "total":100
          }, 
          {
           "person_id" : 3
           "person_name" : "DEF",
           "total":200
         }]
      },
        "place_id" : 4,
        "total" : 10, 
        "empty" : 0,
        "weight" : 54000,
        "persons" : 
          [{
            "person_id" : 2,
            "person_name" : "ABC"
            "total":100
           }, 
           {
            "person_id" : 6
            "person_name" : "GHI",
           }
         ]
     ],
  ),
   Array (
    [added_time] => 2018-12-09 15:00:00+00 
    [id] => 456
    [places] => 
      [{
        "place_id" : 1,
        "total" : 5, 
        "empty" : 0,
        "weight" : 68000,
        "persons" : 
         [{
           "person_id" : 2,
           "person_name" : "ABC",
           "total":200
          }, 
          {
           "person_id" : 3
           "person_name" : "DEF",
           "total":300
         }]
      }]
   )
)

I am trying to get sum on the base of person_id like group by person_id.

My desired result should be:

Array (
 [added_time] => 2018-12-09 14:00:00+00 
 [id] => 123
 persons:array(
   Array([0]=>
     [person_id] : 2,
     [person_name] : "ABC",
     [total]:200
   ),
   Array([1]=>
     [person_id] : 3,
     [person_name] : "DEF",
     [total]:300
   ),
   Array([2]=>
     [person_id] : 6,
     [person_name] : "GHI",
     [total]:500
    )
  ),
 [added_time] => 2018-12-09 15:00:00+00 
 [id] => 123
 persons:array(
   Array([0]=>
     [person_id] : 2,
     [person_name] : "ABC",
     [total]:200
   ),
   Array([1]=>
     [person_id] : 3,
     [person_name] : "DEF",
     [total]:300
    )
  )
)

How can I achieve this result. I can use foreach but I don't want to use it because of three iterations.

Is there any other method to achieve this in php and without any performance issue?

3
  • 2
    show us what you've tried so far and why that doesn't work as expected? Commented Dec 10, 2018 at 9:23
  • 1
    Your Question is not clear that what you want to do? Commented Dec 10, 2018 at 9:26
  • Consider using recursive function. Commented Dec 10, 2018 at 11:51

1 Answer 1

2

You can have that by using PHP function as array-merge, array-column, array-reduce.

Let divided that to 3 step:

1.Sum total for all person given list of persons. Define the the following reduce function:

function reduce($carry, $item)
{
    if (!in_array($item["person_name"], array_column($carry, "person_name")))
        $carry[] = $item;
    else {
        foreach($carry as &$person) {
                if ($item["person_name"] == $person["person_name"])
                        $person["total"] += $item["total"];
        }
    }
    return $carry;
}

2.For every element in your array create you output using the reduce from step 1:

function reduceElement($arr) {
        $res = array("added_time" => $arr["time"], "id" => $arr["id"]);
        $persons = array();
        foreach($arr["places"] as $place) {
                $persons = array_merge($persons, $place["persons"]);
        }
        $res["persons"] = array_reduce($persons, "reduce", array());
        return $res;
}

3.Combine it all:

$elemA= array("id"=>1, "time"=>"2018", "places" => array(array("persons" => array(array("person_name" => "ABC", "total" => 100), array("person_name" => "DEF", "total" => 200))), array("persons" => array(array("person_name" => "ABC", "total" => 100), array("person_name" => "GHI", "total" => 100)))));
$elemB = array("id"=>2, "time"=>"2017", "places" => array(array("persons" => array(array("person_name" => "ABC", "total" => 200), array("person_name" => "DEF", "total" => 300)))));
$arr = array($elemA, $elemB);
$res = array();
foreach($arr as $obj)
    $res[] = reduceElement($obj);

print_r($res);

This will give you the require out put

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.