Проверка того, находятся ли элементы одного массива в другом массиве в PHP


у меня есть два массива в PHP следующим образом:

человек:

Array
(
    [0] => 3
    [1] => 20
)

Разыскиваемых Преступников:

Array
(
    [0] => 2
    [1] => 4
    [2] => 8
    [3] => 11
    [4] => 12
    [5] => 13
    [6] => 14
    [7] => 15
    [8] => 16
    [9] => 17
    [10] => 18
    [11] => 19
    [12] => 20
)

Как проверить, если любой на человек элементы находятся в Разыскиваемых Преступников массив?

в этом примере, он должен вернуть true, потому что 20 - в Разыскиваемых Преступников.

спасибо заранее.

6 88

6 ответов:

можно использовать array_intersect().

$result = !empty(array_intersect($people, $criminals));

нет ничего плохого в использовании array_intersect () и count () (вместо пустого).

например:

$bFound = (count(array_intersect($criminals, $people))) ? true : false;

Если "пустой" не лучший выбор, как насчет этого:

if (array_intersect($people, $criminals)) {...} //when found

или

if (!array_intersect($people, $criminals)) {...} //when not found

этот код является недопустимым, так как вы можете передавать переменные только в языковые конструкции. empty() языковая конструкция.

вы должны сделать это в две строки:

$result = array_intersect($people, $criminals);
$result = !empty($result);

тест производительности для in_array vs array_intersect:

$a1 = array(2,4,8,11,12,13,14,15,16,17,18,19,20);

$a2 = array(3,20);

$intersect_times = array();
$in_array_times = array();
for($j = 0; $j < 10; $j++)
{
    /***** TEST ONE array_intersect *******/
    $t = microtime(true);
    for($i = 0; $i < 100000; $i++)
    {
        $x = array_intersect($a1,$a2);
        $x = empty($x);
    }
    $intersect_times[] = microtime(true) - $t;


    /***** TEST TWO in_array *******/
    $t2 = microtime(true);
    for($i = 0; $i < 100000; $i++)
    {
        $x = false;
        foreach($a2 as $v){
            if(in_array($v,$a1))
            {
                $x = true;
                break;
            }
        }
    }
    $in_array_times[] = microtime(true) - $t2;
}

echo '<hr><br>'.implode('<br>',$intersect_times).'<br>array_intersect avg: '.(array_sum($intersect_times) / count($intersect_times));
echo '<hr><br>'.implode('<br>',$in_array_times).'<br>in_array avg: '.(array_sum($in_array_times) / count($in_array_times));
exit;

вот результаты:

0.26520013809204
0.15600109100342
0.15599989891052
0.15599989891052
0.1560001373291
0.1560001373291
0.15599989891052
0.15599989891052
0.15599989891052
0.1560001373291
array_intersect avg: 0.16692011356354

0.015599966049194
0.031199932098389
0.031200170516968
0.031199932098389
0.031200885772705
0.031199932098389
0.031200170516968
0.031201124191284
0.031199932098389
0.031199932098389
in_array avg: 0.029640197753906

in_array по крайней мере в 5 раз быстрее. Заметьте, что мы "ломаемся", как только результат найден.

вы также можете использовать in_array следующим образом:

<?php
$found = null;
$people = array(3,20,2);
$criminals = array( 2, 4, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
foreach($people as $num) {
    if (in_array($num,$criminals)) {
        $found[$num] = true;
    } 
}
var_dump($found);
// array(2) { [20]=> bool(true)   [2]=> bool(true) }

хотя array_intersect, безусловно, более удобен в использовании, оказывается, что он не очень превосходит по производительности. Я тоже создал этот скрипт:

<?php
$found = null;
$people = array(3,20,2);
$criminals = array( 2, 4, 8, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
$fastfind = array_intersect($people,$criminals);
var_dump($fastfind);
// array(2) { [1]=> int(20)   [2]=> int(2) }

затем я запустил оба фрагмента соответственно в: http://3v4l.org/WGhO7/perf#tabs и http://3v4l.org/g1Hnu/perf#tabs и проверил работоспособность каждого. Интересно то, что общее процессорное время, т. е. пользователь время + системное время одинаково для PHP5. 6, и память также одинакова. Общее время процессора под PHP5.4 меньше для in_array, чем array_intersect, хотя и незначительно.