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

前端 未结 7 1812
闹比i
闹比i 2020-11-27 13:26

I have two arrays in PHP as follows:

People:

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

Wanted Criminals:

相关标签:
7条回答
  • 2020-11-27 13:34

    You can use array_intersect().

    $result = !empty(array_intersect($people, $criminals));
    
    0 讨论(0)
  • 2020-11-27 13:37

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

    You have to do this in two lines:

    $result = array_intersect($people, $criminals);
    $result = !empty($result);
    
    0 讨论(0)
  • 2020-11-27 13:46

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

    For example:

    $bFound = (count(array_intersect($criminals, $people))) ? true : false;
    
    0 讨论(0)
  • 2020-11-27 13:53

    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
    
    0 讨论(0)
  • 2020-11-27 13:53

    You could also use in_array as follows:

    <?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:

    <?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#tabs and http://3v4l.org/g1Hnu/perf#tabs and 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.

    0 讨论(0)
  • 2020-11-27 13:53

    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?

    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 = 'alice@bob.com';
    

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

    // 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 part is the two if statements that are executed synchronously.

    array_key_exists() and in_array() are PHP functions.

    source:

    • https://php.net/manual/en/function.array-key-exists.php

    • https://php.net/manual/en/function.in-array.php

    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 value are 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 /in-use/accounts/account_name/Bob's Drywall (you may need to uri encode the last part, but usually not)

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

    GET /in-use/users/email/alice@bob.com

    Notice also that no one can do:

    GET /in-use/users/password/dogmeat1337 because password is not listed in your list of allowed columns for user.

    Good luck on your journey.

    0 讨论(0)
提交回复
热议问题