检查一个数组的元素是否在 PHP 中的另一个数组中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/523796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:58:56  来源:igfitidea点击:

Checking to see if one array's elements are in another array in PHP

phparrays

提问by Philip Morton

I have two arrays in PHP as follows:

我在 PHP 中有两个数组,如下所示:

People:

人们:

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

Wanted Criminals:

通缉犯:

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
)

How do I check if anyof the Peopleelements are in the Wanted Criminalsarray?

如何检查是否所有的的人们元素是在通缉犯阵列?

In this example, it should return truebecause 20is in Wanted Criminals.

在这个例子中,它应该返回,true因为20通缉犯

回答by Greg

You can use array_intersect().

您可以使用array_intersect().

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

回答by papsy

There's little wrong with using array_intersect() and count() (instead of empty).

使用 array_intersect() 和 count()(而不是空)没有什么问题。

For example:

例如:

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

回答by ihtus

if 'empty' is not the best choice, what about this:

如果“空”不是最佳选择,那么这个呢:

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

or

或者

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

回答by Paul Dragoonis

That code is invalid as you can only pass variables into language constructs. empty()is a language construct.

该代码无效,因为您只能将变量传递到语言结构中。empty()是一种语言结构。

You have to do this in two lines:

你必须在两行中做到这一点:

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

回答by Frank Forte

Performance test for in_arrayvs array_intersect:

in_arrayvs 的性能测试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;

Here are the results:

结果如下:

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_arrayis at least 5 times faster. Note that we "break" as soon as a result is found.

in_array至少快 5 倍。请注意,一旦找到结果,我们就会“中断”。

回答by agm1984

Here's a way I am doing it after researching it for a while. I wanted to make a Laravel API endpoint that checks if a field is "in use", so the important information is: 1) which DB table? 2) what DB column? and 3) is there a value in that column that matches the search terms?

这是我研究了一段时间后正在做的一种方法。我想制作一个 Laravel API 端点来检查一个字段是否“正在使用”,所以重要的信息是:1)哪个数据库表?2)什么数据库列?3) 该列中是否有与搜索词匹配的值?

Knowing this, we can construct our associative array:

知道了这一点,我们可以构造我们的关联数组:

$SEARCHABLE_TABLE_COLUMNS = [
    'users' => [ 'email' ],
];

Then, we can set our values that we will check:

然后,我们可以设置要检查的值:

$table = 'users';
$column = 'email';
$value = '[email protected]';

Then, we can use array_key_exists()and in_array()with eachother to execute a one, two step combo and then act upon the truthycondition:

然后,我们可以使用array_key_exists()and in_array()witheachother 执行一个一两步组合,然后根据truthy条件采取行动:

// step 1: check if 'users' exists as a key in `$SEARCHABLE_TABLE_COLUMNS`
if (array_key_exists($table, $SEARCHABLE_TABLE_COLUMNS)) {

    // step 2: check if 'email' is in the array: $SEARCHABLE_TABLE_COLUMNS[$table]
    if (in_array($column, $SEARCHABLE_TABLE_COLUMNS[$table])) {

        // if table and column are allowed, return Boolean if value already exists
        // this will either return the first matching record or null
        $exists = DB::table($table)->where($column, '=', $value)->first();

        if ($exists) return response()->json([ 'in_use' => true ], 200);
        return response()->json([ 'in_use' => false ], 200);
    }

    // if $column isn't in $SEARCHABLE_TABLE_COLUMNS[$table],
    // then we need to tell the user we can't proceed with their request
    return response()->json([ 'error' => 'Illegal column name: '.$column ], 400);
}

// if $table isn't a key in $SEARCHABLE_TABLE_COLUMNS,
// then we need to tell the user we can't proceed with their request
return response()->json([ 'error' => 'Illegal table name: '.$table ], 400);

I apologize for the Laravel-specific PHP code, but I will leave it because I think you can read it as pseudo-code. The important partis the two ifstatements that are executed synchronously.

我为 Laravel 特定的 PHP 代码道歉,但我会保留它,因为我认为您可以将其视为伪代码。重要的部分if同步执行的两条语句。

array_key_exists()and in_array()are PHP functions.

array_key_exists()in_array()是 PHP 函数。

source:

来源:

The nice thing about the algorithm that I showed above is that you can make a REST endpoint such as GET /in-use/{table}/{column}/{value}(where table, column, and valueare variables).

我上面展示的算法的好处是您可以创建一个 REST 端点,例如GET /in-use/{table}/{column}/{value}(where table, column, and valueare variables)。

You could have:

你可以有:

$SEARCHABLE_TABLE_COLUMNS = [
    'accounts' => [ 'account_name', 'phone', 'business_email' ],
    'users' => [ 'email' ],
];

and then you could make GET requests such as:

然后你可以发出 GET 请求,例如:

GET /in-use/accounts/account_name/Bob's Drywall(you may need to uri encode the last part, but usually not)

GET /in-use/accounts/account_name/Bob's Drywall(您可能需要对最后一部分进行 uri 编码,但通常不需要)

GET /in-use/accounts/phone/888-555-1337

GET /in-use/accounts/phone/888-555-1337

GET /in-use/users/email/[email protected]

GET /in-use/users/email/[email protected]

Notice also that no one can do:

另请注意,没有人可以做到:

GET /in-use/users/password/dogmeat1337because passwordis not listed in your list of allowed columns for user.

GET /in-use/users/password/dogmeat1337因为password未列在您的允许列列表中user

Good luck on your journey.

祝你好运。

回答by slevy1

You could also use in_array as follows:

您还可以使用 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) }

While array_intersect is certainly more convenient to use, it turns out that its not really superior in terms of performance. I created this script too:

虽然 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) }

Then, I ran both snippets respectively at: http://3v4l.org/WGhO7/perf#tabsand http://3v4l.org/g1Hnu/perf#tabsand checked the performance of each. The interesting thing is that the total CPU time, i.e. user time + system time is the same for PHP5.6 and the memory also is the same. The total CPU time under PHP5.4 is less for in_array than array_intersect, albeit marginally so.

然后,我分别在http://3v4l.org/WGhO7/perf#tabshttp://3v4l.org/g1Hnu/perf#tabs 上运行了两个片段,并检查了每个片段的性能。有趣的是,PHP5.6 的总CPU 时间,即用户时间+ 系统时间是一样的,内存也是一样的。在 PHP5.4 下,in_array 的总 CPU 时间比 array_intersect 少,尽管略微如此。