开发者

in_array multiple values

How do I check for开发者_C百科 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.


Intersect the targets with the haystack and make sure the intersection count is equal to the target's count:

$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
 }


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) || ...


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
}


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


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!


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.


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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜