skip to Main Content

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

2

Answers


  1. You should:

    1. Create a location property for each agent.
    2. While going through the records, figure out which agent and location the transaction belongs to. Then, place the transaction in the right location under the correct agent.

    $agentIndex = [];
    $locationIndex = [];
    
    // moving to the index to quick lookup.
    foreach ($agents as $agent) {
        $agent->locations = [];
        $agentIndex[$agent->id] = $agent;
    }
    
    foreach ($locations as $location) {
        $location->transactions = [];
        $locationIndex[$location->xid] = $location;
    }
    
    
    foreach ($records as $record) {
        $agent = $agentIndex[$record->agent_id] ?? null;
        $location = $locationIndex[$record->location_id] ?? null;
    
        if ($agent && $location) {
            // Add location to the agent does not exist
            if (!isset($agent->locations[$location->xid])) {
                $agent->locations[$location->xid] = $location;
            }
            $agent->locations[$location->xid]->transactions[] = $record;
        }
    }
    
    // mapping again with an indexed array
    foreach ($agents as $agent) {
        $agent->locations = array_values($agent->locations);
    }
    
    print_r($agents);
    

    Moved the location inside the foreach.

    $agentIndex = [];
    $locationIndex = [];
    
    foreach ($agents as $agent) {
        $agent->locations = [];
        $agentIndex[$agent->id] = $agent;
    }
    
    foreach ($locations as $location) {
        $locationIndex[$location->xid] = $location;
    }
    
    foreach ($records as $record) {
        $agent = $agentIndex[$record->agent_id] ?? null;
        
        if (isset($locationIndex[$record->location_id])) {
            $location = clone $locationIndex[$record->location_id];
        } else {
            $location = null;
        }
    
        if ($agent && $location) {
            if (!isset($agent->locations[$location->xid])) {
                $location->transactions = [];  
                $agent->locations[$location->xid] = $location;
            }
            $agent->locations[$location->xid]->transactions[] = $record;
        }
    }
    
    
    foreach ($agents as $agent) {
        $agent->locations = array_values($agent->locations);
    }
    
    print_r($agents);
    
    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search