php 检查一个数组的任何元素是否在另一个数组中

lrl1mhuk  于 2023-01-12  发布在  PHP
关注(0)|答案(8)|浏览(229)

我在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
)

如何检查 People 元素中是否有任何元素在 Wanted Criminals 数组中?
在本例中,它应该返回true,因为20Wanted Criminals 中。

jm81lzqq

jm81lzqq1#

您可以使用array_intersect()

$peopleContainsCriminal = !empty(array_intersect($people, $criminals));
oewdyzsn

oewdyzsn2#

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

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

wnrlj8wa3#

如果“空”不是最好的选择,那么这个怎么样:

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

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

vc9ivgsu4#

该代码无效,因为只能将变量传递到语言构造中。empty()是语言构造。
您必须在两行中执行此操作:

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

slsn1g295#

in_array与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倍。注意,我们一找到结果就“中断”。

uwopmtnx

uwopmtnx6#

也可以按如下方式使用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,并检查了每一个的性能。有趣的是,总的CPU时间,即用户时间+系统时间是相同的PHP5.6和内存也是相同的。在PHP5.4下,总的CPU时间是较少的in_array比数组_intersect,虽然边际如此。

yptwkmov

yptwkmov7#

下面是我研究了一段时间后的一种方法。我想做一个Laravel API端点来检查字段是否“正在使用”,所以重要的信息是:1)哪个数据库表?2)哪个数据库列?3)该列中是否有与搜索项匹配的值?
知道了这一点,我们就可以构造关联数组了:

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

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

$table = 'users';
$column = 'email';
$value = 'alice@bob.com';

然后,我们可以使用array_key_exists()in_array()来执行一步、两步组合,然后根据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);

对于Laravel特有的PHP代码,我表示歉意,但是我将不去管它,因为我认为您可以将它作为伪代码来阅读。重要的部分是同步执行的两个if语句。
array_key_exists()in_array()是PHP函数。
资料来源:

我在上面展示的算法的优点在于,您可以创建一个REST端点,例如GET /in-use/{table}/{column}/{value}(其中tablecolumnvalue是变量)。
您可以:

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

然后您可以发出GET请求,例如:
GET /in-use/accounts/account_name/Bob's Drywall(您可能需要对最后一部分进行URI编码,但通常不需要)
x1米11米1x
GET /in-use/users/email/alice@bob.com
还请注意,没有人可以:
GET /in-use/users/password/dogmeat1337,因为password未列在user的允许列列表中。
祝你旅途顺利。

ukqbszuj

ukqbszuj8#

我已经创建了一个干净的帮助函数供您使用。

if (!function_exists('array_has_one')) {

/**
 * array_has_one
 * 
 * Uses the search array to match at least one of the haystack to return TRUE
 * 
 * @param {array} $search
 * @param {array} $haystack
 * @return {boolean}
 */
function array_has_one(array $search, array $haystack){
    if(!count(array_intersect($search, $haystack)) === FALSE){
        return TRUE;
    }else{
        return FALSE;
    }

}
}

你会用这个

if(array_has_one([1,2,3,4,5], [5,6,7,8,9])){
  echo "FOUND 5";
}

相关问题