in_array multiple values

PhpArrays

Php Problem Overview


How do I check for multiple values, such as:

$arg = array('foo','bar');

if(in_array('foo','bar',$arg))

That's an example so you understand a bit better, I know it won't work.

Php Solutions


Solution 1 - Php

Intersect the targets with the haystack and make sure the intersection is precisely equal to the targets:

$haystack = array(...);

$target = array('foo', 'bar');

if(count(array_intersect($haystack, $target)) == count($target)){
    // all of $target is in $haystack
}

Note that you only need to verify the size of the resulting intersection is the same size as the array of target values to say that $haystack is a superset of $target.

To verify that at least one value in $target is also in $haystack, you can do this check:

 if(count(array_intersect($haystack, $target)) > 0){
     // at least one of $target is in $haystack
 }

Solution 2 - Php

Searching the array for multiple values corresponds to the set operations (set difference and intersection), as you will see below.

In your question, you do not specify which type of array search you want, so I am giving you both options.

ALL needles exist

function in_array_all($needles, $haystack) {
   return empty(array_diff($needles, $haystack));
}

$animals = ["bear", "tiger", "zebra"];
echo in_array_all(["bear", "zebra"], $animals); // true, both are animals
echo in_array_all(["bear", "toaster"], $animals); // false, toaster is not an animal

ANY of the needles exist

function in_array_any($needles, $haystack) {
   return !empty(array_intersect($needles, $haystack));
}

$animals = ["bear", "tiger", "zebra"];
echo in_array_any(["toaster", "tiger"], $animals); // true, tiger is an amimal
echo in_array_any(["toaster", "brush"], $animals); // false, no animals here

Important consideration

If the set of needles you are searching for is small and known upfront, your code might be clearer if you just use the logical chaining of in_array calls, for example:

$animals = ZooAPI.getAllAnimals();
$all = in_array("tiger", $animals) && in_array("toaster", $animals) && ...
$any = in_array("bear", $animals) || in_array("zebra", $animals) || ...

Solution 3 - Php

if(in_array('foo',$arg) && in_array('bar',$arg)){
    //both of them are in $arg
}

if(in_array('foo',$arg) || in_array('bar',$arg)){
    //at least one of them are in $arg
}

Solution 4 - Php

Going off of @Rok Kralj answer (best IMO) to check if any of needles exist in the haystack, you can use (bool) instead of !! which sometimes can be confusing during code review.

function in_array_any($needles, $haystack) {
   return (bool)array_intersect($needles, $haystack);
}

echo in_array_any( array(3,9), array(5,8,3,1,2) ); // true, since 3 is present
echo in_array_any( array(4,9), array(5,8,3,1,2) ); // false, neither 4 nor 9 is present

https://glot.io/snippets/f7dhw4kmju

Solution 5 - Php

IMHO Mark Elliot's solution's best one for this problem. If you need to make more complex comparison operations between array elements AND you're on PHP 5.3, you might also think about something like the following:

<?php

// First Array To Compare
$a1 = array('foo','bar','c');

// Target Array
$b1 = array('foo','bar');


// Evaluation Function - we pass guard and target array
$b=true;
$test = function($x) use (&$b, $b1) {
        if (!in_array($x,$b1)) {
                $b=false;
        }
};


// Actual Test on array (can be repeated with others, but guard 
// needs to be initialized again, due to by reference assignment above)
array_walk($a1, $test);
var_dump($b);

This relies on a closure; comparison function can become much more powerful. Good luck!

Solution 6 - Php

if(empty(array_intersect([21,22,23,24], $check_with_this)) {
 print "Not found even a single element";
} else {
 print "Found an element";
}

array_intersect() returns an array containing all the values of array1 that are present in all the arguments. Note that keys are preserved.

Returns an array containing all of the values in array1 whose values exist in all of the parameters.


empty() — Determine whether a variable is empty

Returns FALSE if var exists and has a non-empty, non-zero value. Otherwise returns TRUE.

Solution 7 - Php

If you're looking to optimize this search with just a comparison check only I would do:

public function items_in_array($needles, $haystack)
{
    foreach ($needles as $needle) {
        if (!in_array($needle, $haystack)) {
            return false;
        }
    }

    return true;
}

if you're willing to do it ugly doing multiple if(in_array(...&&in_array(... is even faster.

I did a test with 100 and another with 100,000 array elements and between 2 and 15 needles using array_intersect, array_diff, and in_array.

in_array was always significantly faster even when I had to do it 15x for different needles. array_diff was also quite a bit faster than array_intersect.

So if you're just trying to search for a couple of things to see if they exist in an array in_array() is best performance-wise. If you need to know the actual differences/matches then it's probably just easier to use array_diff/array_intersect.

Feel free to let me know if I did my calculations wrong in the ugly example below.

<?php



$n1 = rand(0,100000);
$n2 = rand(0,100000);
$n2 = rand(0,100000);
$n3 = rand(0,100000);
$n4 = rand(0,100000);
$n5 = rand(0,100000);
$n6 = rand(0,100000);
$n7 = rand(0,100000);
$n8 = rand(0,100000);
$n9 = rand(0,100000);
$n10 = rand(0,100000);
$n11 = rand(0,100000);
$n12 = rand(0,100000);
$n13 = rand(0,100000);
$n14 = rand(0,100000);
$n15 = rand(0,100000);
$narr = [$n1, $n2, $n3, $n4, $n5, $n6, $n7, $n8, $n9, $n10, $n11, $n12, $n13, $n14, $n15];

$arr = [];
for($i = 0; $i<100000 ; $i++)
{
	
	$arr[] = rand(0,100000);
	
}


function array_in_array($needles, $haystack)
{
	foreach($needles as $needle)
	{
	
		if (!in_array($needle, $haystack))
			{
				return false;
			}

	}
	
	return true;
}

$start_time = microtime(true);
$failed = true;
if(array_in_array($narr, $arr))
{
	echo "<br>true0<br>";
}

$total_time = microtime(true) - $start_time;
echo "<hr>";
echo($total_time);



$start_time = microtime(true);

if (
    in_array($n1, $arr) !== false &&
    in_array($n2, $arr) !== false &&
    in_array($n3, $arr) !== false &&
    in_array($n4, $arr) !== false &&
    in_array($n5, $arr) !== false &&
    in_array($n6, $arr) !== false &&
    in_array($n7, $arr) !== false &&
    in_array($n8, $arr) !== false &&
    in_array($n9, $arr) !== false &&
    in_array($n10, $arr) !== false &&
    in_array($n11, $arr) !== false &&
    in_array($n12, $arr) !== false &&
    in_array($n13, $arr) !== false &&
    in_array($n14, $arr) !== false &&
    in_array($n15, $arr)!== false) {
    echo "<br>true1<br>";
}

$total_time = microtime(true) - $start_time;
echo "<hr>";
echo($total_time);

$first_time = $total_time;

echo "<hr>";

$start_time = microtime(true);

if (empty($diff = array_diff($narr,$arr)))
{

	echo "<br>true2<br>";
}


$total_time = microtime(true) - $start_time;
echo($total_time);
print_r($diff);
echo "<hr>";

echo "<hr>";
if ($first_time > $total_time)
{
	echo "First time was slower";
}

if ($first_time < $total_time)
{
	echo "First time was faster";
}

echo "<hr>";


$start_time = microtime(true);

if (count(($itrs = array_intersect($narr,$arr))) == count($narr))
{

	echo "<br>true3<br>";
	print_r($result);
}


$total_time = microtime(true) - $start_time;
echo "<hr>";
echo($total_time);

print_r($itrs);

echo "<hr>";

if ($first_time < $total_time)
{
	echo "First time was faster";
}


echo "<hr>";
print_r($narr);
echo "<hr>";
print_r($arr);

Solution 8 - Php

Expanding on @Rok Kralj answer above https://stackoverflow.com/a/11040612/436443

If your $needles, or $haystack is null you get an error:

PHP Warning:  array_intersect(): Expected parameter 1 to be an array, null given

In dynamic environment feeding wrong argument type happens.

Method should be able to handle that.

Here is my quick take.

function in_array_any($needles, $haystack) {

$needles = is_array($needles) ? $needles : [];
$haystack = is_array($haystack) ? $haystack : [];

return !empty(array_intersect($needles, $haystack));

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondarylView Question on Stackoverflow
Solution 1 - PhpMark ElliotView Answer on Stackoverflow
Solution 2 - PhpRok KraljView Answer on Stackoverflow
Solution 3 - PhpRiaDView Answer on Stackoverflow
Solution 4 - PhpsMylesView Answer on Stackoverflow
Solution 5 - PhpmaraspinView Answer on Stackoverflow
Solution 6 - PhpUmesh PatilView Answer on Stackoverflow
Solution 7 - PhpEricView Answer on Stackoverflow
Solution 8 - PhpJeffzView Answer on Stackoverflow