Checking for the presence of one element of an array in another array in PHP

I have two arrays in PHP as follows:

People:

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

Criminals required:

 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 to verify that any People items are in the Wanted Criminals array?

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

Thanks in advance.

+108
arrays php
Feb 07 '09 at 13:48
source share
7 answers

You can use array_intersect() .

 $result = !empty(array_intersect($people, $criminals)); 
+163
Feb 07 '09 at 13:50
source share

Not so bad with using array_intersect () and count () (instead of empty).

For example:

 $bFound = (count(array_intersect($criminals, $people))) ? true : false; 
+29
Jan 05 2018-12-12T00:
source share

if "empty" is not the best choice, what about it:

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

or

 if (!array_intersect($people, $criminals)) {...} //when not found 
+23
Nov 12 '13 at
source share

This code is invalid because you can only pass variables to language constructs. empty() is a language construct.

You must do this in two lines:

 $result = array_intersect($people, $criminals); $result = !empty($result); 
+21
Jul 28 '10 at 14:40
source share

Performance test for 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; 

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_array is at least 5 times faster. Please note that we β€œbreak” as soon as the result is found.

+16
Jun 18 '15 at 15:12
source share

You can 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 it is not superior in terms of performance. I also created this script:

 <?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 performed both fragments respectively: http://3v4l.org/WGhO7/perf#tabs and http://3v4l.org/g1Hnu/perf#tabs and check the performance of each of them. The interesting thing is that the total processor time, that is, user time + system time for PHP5.6 is the same, and also the same. The total processor time in PHP5.4 is less for in_array than array_intersect, albeit slightly.

+1
Nov 05 '14 at 20:02
source share

Here is the way I have been doing this after researching for some time. I wanted to create a Laravel API endpoint that checks if a field is used, so the important information is: 1) what is the database table? 2) which database column? and 3) is there a value in this column that matches the search terms?

Knowing this, we can build our associative array:

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

Then we can set our values, which 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-stage combo and then 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 pseudocode. The important part is two if that execute synchronously.

array_key_exists() and in_array() are PHP functions.

source:

The good thing about the algorithm I showed above is that you can create 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 can make GET requests, such as:

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

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

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

Note that no one can do:

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

Good luck on your journey.

+1
May 03 '19 at 6:38
source share



All Articles