php merge two arrays

Viewed 36

I have two arrays which i want to merge but following certain conditions.

$wt = [
    ['time' =>'07:00'],
    ['time' =>'07:30'],
    ['time' =>'08:00'],
    ['time' =>'08:30'],
    ['time' =>'09:00'],
    ['time' =>'09:30'],
];

$tasks = [
    ['time' => '07:30', 'name' => 'john'],
    ['time' => '08:00', 'name' => 'fred'],
];

The desired result should look like this:

$full = [
    ['time' => '07:00', 'name' => null],
    ['time' => '07:30', 'name' => 'john'],
    ['time' => '08:00', 'name' => 'fred'],
    ['time' => '08:30', 'name' => null],
    ['time' => '09:00', 'name' => null],
    ['time' => '09:30', 'name' => null],
];

I'm looping, but I'm making a mistake somewhere.



$full = []; // this is the merge array
foreach ($wt as $k => $item) {
    $full[$k]['time'] = $item['time'];
    foreach ($tasks as $task) {
        if($item['time'] == $task['time']) {
            $full[$k]['name'] = $task['name'];  
        } else {
            $full[$k]['name'] = null;
        }
    }   
}

Here is my wrong result...

Array
(
    [0] => Array
        (
            [time] => 07:00
            [name] => 
        )

    [1] => Array
        (
            [time] => 07:30
            [name] => 
        )

    [2] => Array
        (
            [time] => 08:00
            [name] => fred
        )

    [3] => Array
        (
            [time] => 08:30
            [name] => 
        )

    [4] => Array
        (
            [time] => 09:00
            [name] => 
        )

    [5] => Array
        (
            [time] => 09:30
            [name] => 
        )

)

I'm losing 'john'

It should be done so that the first array is detected with the second. So, by matching time from the first one, fill the array 'full' with the name. Otherwise, it should be left blank.

Can anyone help? Thank you.

1 Answers

What happens here is caused because you contniue looping even when you match the result at first, and then in the other iterations you just nulling the already matched result:

foreach ($tasks as $task) {
    if($item['time'] == $task['time']) {
        $full[$k]['name'] = $task['name'];  
    } else {
        $full[$k]['name'] = null;
    }
} 

If you will debug it:

  1. Match 07:30 to 07:30 - that's okay and you are setting the name in $k position.
  2. Not matching 07:30 to 08:00 - insert null to name at $k position.

if you would have a third item in your second array you were loose the second item either, so just add break after you match one value.

foreach ($tasks as $task) {
    if($item['time'] == $task['time']) {
        $full[$k]['name'] = $task['name'];
        break;  
    } 
    $full[$k]['name'] = null;
    
} 

That's said I want to suggest more elegant way to do this:

$wt = [
    ['time' =>'07:00'],
    ['time' =>'07:30'],
    ['time' =>'08:00'],
    ['time' =>'08:30'],
    ['time' =>'09:00'],
    ['time' =>'09:30'],
];

$tasks = [
    ['time' => '07:30', 'name' => 'john'],
    ['time' => '08:00', 'name' => 'fred'],
];

$tasks_time_values = array_column($tasks, 'time');
$tasks_name_values = array_column($tasks, 'name');

$new_tasks = array_combine($tasks_time_values, $tasks_name_values);

print_r($new_tasks);

$full = array_map(function ($w) use ($new_tasks) {
    $w['name'] = $new_tasks[$w['time']] ?? null;
    return $w;
}, $wt);

print_r($full);

Outputs:

Array
(
    [07:30] => john
    [08:00] => fred
)
Array
(
    [0] => Array
        (
            [time] => 07:00
            [name] => 
        )

    [1] => Array
        (
            [time] => 07:30
            [name] => john
        )

    [2] => Array
        (
            [time] => 08:00
            [name] => fred
        )

    [3] => Array
        (
            [time] => 08:30
            [name] => 
        )

    [4] => Array
        (
            [time] => 09:00
            [name] => 
        )

    [5] => Array
        (
            [time] => 09:30
            [name] => 
        )

)

Demo Here

Related