猿问

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

我需要像这样比较两个数组


// 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]

);

第一个数组表示当前数据库中的数据,而第二个数组表示从 -file 传递的数据。csv


为了不从数据库中删除整个数据,我需要比较两个数组。如果 -file 提供的数据不在数据库中,我想输入这些数据集。如果数据库包含的数据不在 -file 中,我想从数据库中删除它们。csvcsv


我想出了一个适用于数组中少量数据的解决方案:


$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秒的执行时间。


我该如何解决这个问题?我想算法应该更有效率。


森栏
浏览 129回答 2
2回答

catspeake

您可以按 索引每个数组,然后计算键中的差值: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);若要比较整个数组内容(如果只添加多个和),则可以映射每个数组并序列化为字符串表示形式并进行比较。请注意,元素的顺序也很重要:idanother_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)));在演示站点上,这个适用于40,000个数组项目,但不是50,000个。这将取决于您的资源和设置。php.ini还有一个array_intersect_key,如果你想看到每个数组中有什么相同,array_intersect。

慕虎7371278

你正在做很多循环。,并使用大量时间。foreacharray_filterarray_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;    }});这样可以减少迭代次数,从而获得所需的结果。
随时随地看视频慕课网APP
我要回答