为了账号安全,请及时绑定邮箱和手机立即绑定

比较两个多维和关联数组并获得差异

比较两个多维和关联数组并获得差异

PHP
临摹微笑 2022-07-22 18:44:51
我需要像这样比较两个数组// currently in our database$firstArr = array(        ["id"=>1, "another_id"=>1],        ["id"=>2, "another_id"=>4],        ["id"=>5, "another_id"=>9]);// currently fetched from csv-files$secondArr = array(        ["id"=>6, "another_id"=>3],        ["id"=>2, "another_id"=>7],        ["id"=>1, "another_id"=>1]);第一个数组表示当前在我们数据库中的数据,同时第二个表示从csv-file 传递的数据。为了不从数据库中删除整个数据,我需要比较两个数组。如果csv-file 提供了不在数据库中的数据,我想输入这些数据集。如果数据库包含不在csv-file 中的数据,我想将它们从数据库中删除。我想出了一个适用于数组中少量数据的解决方案:$new_to_database = array();foreach($secondArr AS $arr){    $in_database = array_filter(array_map(function($el) use ($arr){        if($el['id'] == $arr['id'] && $el['another_id'] == $arr['another_id']){            return $el;        }    }, $firstArr));    if(count($in_database) === 0){        $new_to_database[] = $arr;    }               }var_dump($new_to_database);   // input later on// array(2) { [0]=> array(2) { ["id"]=> int(6) ["another_id"]=> int(3) } [1]=> array(2) { ["id"]=> int(2) ["another_id"]=> int(7) } }问题是每个数组包含大约 5000 个数据集。结果脚本需要很长时间,并且我收到超过 360 秒的执行时间的错误。我该如何解决这个问题?我想算法应该更有效。
查看完整描述

2 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

您可以通过索引每个数组,id然后计算键的差异:


// Get items that are in CSV but not in database

$new = array_diff_key(array_column($csv, null, 'id'), array_column($db, null, 'id'));


// Get items that are in database but not in CSV

$del = array_diff_key(array_column($db, null, 'id'), array_column($csv, null, 'id'));

这是一个使用两个简单数组的演示,每个数组包含 50,000 个项目。


这很简短,但您可能不想array_column多次运行:


$csv = array_column($csv, null, 'id');

$db  = array_column($db, null, 'id');


// Get items that are in CSV but not in database

$new = array_diff_key($csv, $db);


// Get items that are in database but not in CSV

$del = array_diff_key($db, $csv);

要比较整个数组内容(如果您添加的不仅仅是idand ,这将起作用another_id),您可以将每个数组映射并序列化为字符串表示形式并进行比较。请注意,元素的顺序也很重要:


// Get items that are in CSV but not in database

$new = array_map('unserialize',

                 array_diff(array_map('serialize', $csv), array_map('serialize', $db)));


// Get items that are in database but not in CSV        

$del = array_map('unserialize',

                 array_diff(array_map('serialize', $db), array_map('serialize', $csv)));

在 DEMO 站点上,这个适用于 40,000 个数组项,但不是 50,000 个。这将取决于您的资源和php.ini设置。


如果您想查看每个数组中的相同内容,还有一个array_intersect_keyarray_intersect 。


查看完整回答
反对 回复 2022-07-22
?
温温酱

TA贡献1752条经验 获得超4个赞

你正在做很多循环。foreach,array_filter并array_map使用大量时间。


$new_to_database = array_udiff($secondArr, $firstArr, function ($s, $f) {

    if ($s['id'] == $f['id'] && $s['another_id'] == $f['another_id']) {

        return 0;

    } else {

        return -1;

    }

});

这以更少的迭代提供了您需要的结果。


查看完整回答
反对 回复 2022-07-22
  • 2 回答
  • 0 关注
  • 96 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信