user3309434
user3309434

Reputation: 21

Merge row data from a 2d array into the objects of an array related by an id and an object value within the row's range

I have an array:

$array1 = [
    (object)[
        'driver_id' => 2,
        'total' => 308,
        'total_driver' => 5,
        'score1' => 61.6000,
        'score2' => 62,
    ],
    (object)[
        'driver_id' => 3,
        'total' => 354,
        'total_driver' => 5,
        'score1' => 70.8000,
        'score2' => 71,
    ],
];

$array2 = [
    [
        'driver_id' => 2,
        'recommendation_min' => 0,
        'recommendation_max' => 50,
        'recommendation_key_range' => 'Low',
        'recommendation_observation' => 'Low',
        'recommendation_' => 'Low',
    ],
    [
        'driver_id' => 2,
        'recommendation_min' => 51,
        'recommendation_max' => 78,
        'recommendation_key_range' => 'Moderate',
        'recommendation_observation' => 'Moderate',
        'recommendation_' => 'Moderate',
    ],
];

How do I merge array to so that the driver_id 2 object looks like this:

[driver_id] => 2
[recommendation_min] => 51
[recommendation_max] => 78
[recommendation_key_range] => Moderate
[recommendation_observation] => Moderate
[recommendation_] => Moderate
[total] => 308
[total_driver] => 5
[score1] => 61.6000
[score2] => 62

A row should be merged with an object when it has the same driver_id and the score2 is between recommendation_min and recommendation_max.

Upvotes: -1

Views: 110

Answers (3)

mickmackusa
mickmackusa

Reputation: 47873

From PHP8.4, you can enjoy the performance of a short-circuiting loop AND functional style programming with array_find(). It will search for a qualifying value (a row in this case) and either return the first qualifier or null if no match is found.

Temporarily cast the each object as an array for the sake of merging with the found array, then revert the updated payload to an object. Demo

var_export(
    array_map(
        fn($obj) => (object)array_merge(
            array_find(
                $array2,
                fn($row) => $obj->driver_id == $row['driver_id']
                    && $obj->score2 >= $row['recommendation_min']
                    && $obj->score2 <= $row['recommendation_max']
            ) ?? [],
            (array)$obj
        ),
        $array1
    )
);

Output:

array (
  0 => 
  (object) array(
     'driver_id' => 2,
     'recommendation_min' => 51,
     'recommendation_max' => 78,
     'recommendation_key_range' => 'Moderate',
     'recommendation_observation' => 'Moderate',
     'recommendation_' => 'Moderate',
     'total' => 308,
     'total_driver' => 5,
     'score1' => 61.6,
     'score2' => 62,
  ),
  1 => 
  (object) array(
     'driver_id' => 3,
     'total' => 354,
     'total_driver' => 5,
     'score1' => 70.8,
     'score2' => 71,
  ),
)

Upvotes: 0

user3335780
user3335780

Reputation: 121

 $drivers = array();
 $drivers[0] = array('driver_id' => 2, 'total' => 308, 'total_driver' => 5, 'score1'   => 61.6, 'score2' => 62 );
 $drivers[1] = array('driver_id' => 3, 'total' => 354, 'total_driver' => 5, 'score1' => 70.8, 'score2' => 71 );
 $drivers[2] = array('driver_id' => 4, 'total' => 354, 'total_driver' => 5, 'score1' => 70.8, 'score2' => 71 );
 $drivers[3] = array('driver_id' => 5, 'total' => 354, 'total_driver' => 5, 'score1' => 70.8, 'score2' => 71 );

 $recommends = array();
 $recommends[0] = array('driver_id' => 2, 'recommendation_min' => 0, 'recommendation_max' => 50, 'recommendation_key_range' => "Low", 'recommendation_observation' => "Low", 'recommendation_' => "Low" );

 $recommends[1] = array('driver_id' => 2, 'recommendation_min' => 51, 'recommendation_max' => 78, 'recommendation_key_range' => "Moderate", 'recommendation_observation' => "Moderate", 'recommendation_' => "Moderate" );
 $recommends[2] = array('driver_id' => 4, 'recommendation_min' => 51, 'recommendation_max' => 78, 'recommendation_key_range' => "Moderate", 'recommendation_observation' => "Moderate", 'recommendation_' => "Moderate" );


 $one = array();
 $matched = array();
 $flag = 0;
 $myarray = array();

 foreach($drivers as $key=>$data){   
    foreach($recommends as $keys=>$dt){
       if($data['driver_id']==$dt['driver_id']){            
          $one = array_merge($data , $dt);
       }
     }

    if(!empty($matched)){
        foreach($matched as $key=>$dta){

           if($dta['driver_id']==$one['driver_id']) 
             $flag = 1;
         }

         if($flag==0){
            $matched[] = $one;
            $myarray[] = $one['driver_id'];
         }

      $flag=0;

     }else{
       $matched[] = $one;
       $myarray[] = $one['driver_id'];
     }
 }
$myarray = array_unique($myarray);

foreach($drivers as $key=>$data){   
    if(!in_array($data['driver_id'] , $myarray)){
       $matched[] = $data;
     }
}

foreach($recommends as $key=>$dta){   
    if(!in_array($dta['driver_id'] , $myarray)){
        $matched[] = $data;
    }
}

echo "<pre>";
print_r($matched);

Upvotes: 0

Durandal
Durandal

Reputation: 5663

Basically just need to use array_merge and a couple of predicate statements to decide which array to merge based on score1 & score2. Something like this should serve:

$drivers = array();
$drivers[0] = array('driver_id' => 2, 'total' => 308, 'total_driver' => 5, 'score1' => 61.6, 'score2' => 62 );
$drivers[1] = array('driver_id' => 3, 'total' => 354, 'total_driver' => 5, 'score1' => 70.8, 'score2' => 71 );

$recommends = array();
$recommends[0] = array('driver_id' => 2, 'recommendation_min' => 0, 'recommendation_max' => 50, 'recommendation_key_range' => "Low", 'recommendation_observation' => "Low", 'recommendation_' => "Low" );
$recommends[1] = array('driver_id' => 2, 'recommendation_min' => 51, 'recommendation_max' => 78, 'recommendation_key_range' => "Moderate", 'recommendation_observation' => "Moderate", 'recommendation_' => "Moderate" );

$results = array();
foreach($drivers as $driver) {
    if($driver['score1'] > 50 || $driver['score2'] > 50) {
        $driver = array_merge($driver,$recommends[1]);
    } else {
        $driver = array_merge($driver, $recommends[0]);
    }
    $results[] = $driver;
}

Upvotes: 1

Related Questions