检查一个数组的元素是否在 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
Checking to see if one array's elements are in another array in PHP
提问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()andin_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#tabs和http://3v4l.org/g1Hnu/perf#tabs 上运行了两个片段,并检查了每个片段的性能。有趣的是,PHP5.6 的总CPU 时间,即用户时间+ 系统时间是一样的,内存也是一样的。在 PHP5.4 下,in_array 的总 CPU 时间比 array_intersect 少,尽管略微如此。

