Search code examples
phparraysfor-looparray-merge

foreach loop and array_merge not matching correctly


I have the following two arrays that I am trying to merge into one where a common order_id is found:

$orders array:

[0] => Array (
    [order_id] => 45145
    [customers_email_address] => [email protected]
    [customers_name] => test name
    )
[1] => Array (
    [order_id] => 45136
    [customers_email_address] => [email protected]
    [customers_name] => test name
    )
[2] => Array (
    [order_id] => 45117
    [customers_email_address] => [email protected]
    [customers_name] => test name
    )
[3] => Array (
    [order_id] => 44959
    [customers_email_address] => [email protected]
    [customers_name] => test name
    )
[4] => Array (
    [order_id] => 44938
    [customers_email_address] => [email protected]
    [customers_name] => t
    )

$chitchattracking array:

[1] => Array (
    [order_id] => 44938
    [carrier_tracking_code] => 9205590221582717655498
    )
[2] => Array (
    [order_id] => 44854
    [carrier_tracking_code] => 92055902215827
    )

in the above array samples there is a match of the order_id: 44938

Here is my code that is checking for the match, and put it into a new array $tracked:

foreach ($orders as $order) {
    if (($key = array_search($order['order_id'], array_column($chitchattracking, 'order_id'))) !== false) {
        $tracked[] = array_merge( $order, $chitchattracking[$key]);
    }
}

somehow i really messed this up and it matched the wrong order_ids and posted the incorrect tracking numbers. further, when I run the code with this limited amount, it is not even finding the match.


Solution

  • Your problem is almost certainly being caused by the fact that array_column returns an array that is numerically indexed starting at 0, regardless of the keys of the input array. So if the input array is not also numerically indexed starting at 0, the key returned by array_search will not necessarily match a key in the input array (this is why your code won't run at all with the sample data in your question). The easiest way to work around this is to re-index $chitchattracking by order_id, then you can do a simple isset check to control the push to $tracking:

    $tracking = array();
    $chitchat = array_column($chitchattracking, null, 'order_id');
    foreach ($orders as $order) {
        $order_id = $order['order_id'];
        if (isset($chitchat[$order_id])) {
            $tracking[] = array_merge($order, $chitchat[$order_id]);
        }
    }
    print_r($tracking);
    

    Output:

    Array
    (
        [0] => Array
            (
                [order_id] => 44938
                [customers_email_address] => [email protected]
                [customers_name] => t
                [carrier_tracking_code] => 9.2055902215827E+21
            )
    )
    

    Demo on 3v4l.org