Как можно сравнить два массива данных?

Как эффективно сравнить два массива, содержащих информацию о пользователях (id, email, name) — один из базы данных, другой получен частями — с целью получения двух новых массивов: пользователей, которых нет в базе данных, и записей из базы данных, которых нет среди пользователей? Учитывая что второй массив приходит частями, как решить данную задачу наиболее оптимальным образом?
  • 9 июня 2024 г. 19:11
Ответы на вопрос 2
Для сравнения двух массивов данных можно использовать циклы и условные операторы. Например, можно пройти по каждому элементу из массива, содержащего часть данных, и для каждого элемента проверить наличие его в базе данных. 

Однако, чтобы сделать этот процесс более эффективным, можно воспользоваться функционалом баз данных. Например, если у вас есть возможность выгрузить данные из массива во временную таблицу базы данных, вы можете выполнить SQL-запрос с использованием операторов JOIN (например, LEFT JOIN или RIGHT JOIN) для сравнения двух таблиц и получения нужных результатов.

Другой способ - использовать функции поиска и фильтрации данных в программах обработки данных, таких как Python с библиотекой Pandas. Вы можете объединить два массива в DataFrame, применить методы поиска по индексам или значениям и получить результаты.

В любом случае, оптимальный способ зависит от объема данных, доступных ресурсов и уровня сложности задачи.
Самое простое, "решение в лоб" 

function getExcluded(array $users, array $emails): array
{
    foreach ($emails as $email => $emailVal) {
        foreach ($users as $key => $user) {
            if ($user['email'] === $email) {
                unset($emails[$email]);
                unset($users[$key]);
                break;
            }
        }
    }

    return [
        'emails' => $emails,
        'users' => $users,
    ];
}


Единственное, могут быть коллизии если в массиве users будут несколько массивов с одинаковым email
Если записей будет более чем 10к, то можно генераторы заюзать https://www.php.net/manual/ru/language.generators....

еще можно как-то так, компактнее:
function getExcluded(array $users, array $emails): array
{
    $emailsFromUsers = [];
    foreach ($users as $key => $user) {
        if (!isset($emailsFromUsers[$user['email']])) {
            $emailsFromUsers[$user['email']] = $user;
        }
    }
 
    return [
    	'emails' => array_diff_key($emails, $emailsFromUsers),
    	'users' => array_diff_key($emailsFromUsers, $emails),
    ];
}


Но опять же, не подходит если может быть несколько элементов в users с одинаковым email, но с разными айди, и, если я правильно все понимаю, это должно быть менее эффективно
Похожие вопросы