цикл foreach и array_merge не совпадают правильно

#php #arrays #for-loop #array-merge

#php #массивы #for-цикл #слияние массивов

Вопрос:

У меня есть следующие два массива, которые я пытаюсь объединить в один, где найден общий order_id:

массив $orders:

 [0] => Array (
    [order_id] => 45145
    [customers_email_address] => test@test.com
    [customers_name] => test name
    )
[1] => Array (
    [order_id] => 45136
    [customers_email_address] => test@yahoo.com
    [customers_name] => test name
    )
[2] => Array (
    [order_id] => 45117
    [customers_email_address] => test@yahoo.com
    [customers_name] => test name
    )
[3] => Array (
    [order_id] => 44959
    [customers_email_address] => test@gmail.com
    [customers_name] => test name
    )
[4] => Array (
    [order_id] => 44938
    [customers_email_address] => test@hotmail.com
    [customers_name] => t
    )
  

$ массив отслеживания сообщений:

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

в приведенных выше образцах массива есть совпадение order_id: 44938

Вот мой код, который проверяет соответствие и помещает его в новый массив $tracked:

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

каким-то образом я действительно все испортил, и он сопоставил неправильные order_ids и разместил неправильные номера отслеживания. кроме того, когда я запускаю код с этим ограниченным объемом, он даже не находит совпадения.

Комментарии:

1. В 0 вашем массиве нет ключа $chitchattracking ?

Ответ №1:

Ваша проблема почти наверняка вызвана тем фактом, что array_column возвращает массив, который численно индексируется, начиная с 0, независимо от ключей входного массива. Поэтому, если входной массив также не проиндексирован численно, начиная с 0, ключ, возвращаемый array_search не обязательно будет соответствовать ключу во входном массиве (вот почему ваш код вообще не будет выполняться с образцом данных в вашем вопросе). Самый простой способ обойти это — переиндексировать $chitchattracking by order_id , затем вы можете выполнить простую isset проверку, чтобы контролировать нажатие на $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);
  

Вывод:

 Array
(
    [0] => Array
        (
            [order_id] => 44938
            [customers_email_address] => test@hotmail.com
            [customers_name] => t
            [carrier_tracking_code] => 9.2055902215827E 21
        )
)
  

Демонстрация на 3v4l.org

Комментарии:

1. Большое спасибо, что указали, что я разочарован, я не понимал, что массив не начинается с 0. этот массив был сгенерирован из некоторого json, и я пытаюсь выяснить, почему он не начинается с 0.

2. и я нашел почему, спасибо, что указали на это и дали мне возможность переиндексировать!

3. @Sackling круто — это бонус. Обратите внимание, что даже с исправленной индексацией этот код будет значительно быстрее, чем код, который вы опубликовали в вопросе, поскольку он вызывается только array_column один раз и не имеет вызовов array_search (что намного медленнее, чем поиск по ключу).