Search code examples
phparraysobjectforeach

properly assign records into correct parent using foreach php


I have a similar arrays like below:

       $agents = [
          (object)["id"=> 301,"name"=> "Agent 1"],
           (object)["id"=> 303,"name"=> "Agent 2"],
           (object)["id"=> 301,"name"=> "Agent 3"],
           (object)["id"=> 305,"name"=> "Agent 4"],
           (object)["id"=> 306,"name"=> "Agent 5"],
           (object)["id"=> 303,"name"=> "Agent 6"]
        ];


         $locations =  [
             (object)["xid"=> 148,"location_name"=> "USA"],
             (object)["xid"=> 149,"location_name"=> "CHINA"],
             (object)["xid"=> 153,"location_name"=> "GERMANY"],
             (object)["xid"=> 156,"location_name"=> "CANADA"],
             (object)["xid"=> 167,"location_name"=> "SINGAPORE"],
             (object)["xid"=> 0,"location_name"=> "No Location"]
        ];

       
        $records = [
           (object)["agent_id"=> 301,"location_id"=> 156,"total"=> 10000],
           (object)["agent_id"=> 303,"location_id"=> 149,"total"=> 13000],
           (object)["agent_id"=> 301,"location_id"=> 156,"total"=> 10000],
           (object)["agent_id"=> 305,"location_id"=> 0,"total"=> 10000],
           (object)["agent_id"=> 306,"location_id"=> 148,"total"=> 10000],
           (object)["agent_id"=> 303,"location_id"=> 0,"total"=> 10000]
        ];

I am trying to assign the correct transactions into $agent->locations->transactions but my loop is not working..

        foreach ($agents as $a) {
            foreach ($locations as $l) {
                $a->locations[]=$l;
                foreach ($records as $r) {
                    if($r->location_id == $l->xid && $r->agent_id == $a->id){
                        $l->transactions[] = $r;
                    }
                }
            }
        }

this is the result

enter image description here

what im trying to achieve is that, the transactions should be assigned/filtered under correct agent.. please help.. been looking on that loop for too long and have no idea how to achieve what i need :( ..

enter image description here


Solution

  • You are dealing with objects. So, any modification made to it will reflect later on.

    You did $l->transactions[] = $r;. So now that $l object will have previous transaction details too.

    To solve this, you can create a quick clone of the object and modify this new object using clone.

    Snippet:

    <?php
    
    foreach($agents as $agent){
        $agent->locations = [];
        foreach($locations as $location){
            $location = clone $location;
            $location->transactions = [];
            foreach($records as $r){
                if($r->agent_id == $agent->id && $location->xid == $r->location_id){
                    $location->transactions[] = $r;
                }
            }
            
            $agent->locations[] = $location;
        }
    }
    

    Live Demo