Thiago
Thiago

Reputation: 117

PHP in_array isn't finding multiple values

In my function, in_array not finding the numbers.

    function genNumbers($min, $max, $quantity, $qtd, $sumMin = false, $sumMax = false)
    {
        for ($i = 0; $i <= $qtd; $i++) {
            $numbers = range($min, $max);
            shuffle($numbers);
            $a = array_slice($numbers, 0, $quantity);
            asort($a);

            $x = array(14, 17);

            if (in_array($x, $a)) {
                continue;
            }

            if ($sumMin) {
                if (array_sum($a) < $sumMin)
                    continue;   
            }

            if ($sumMax) {
                if (array_sum($a) > $sumMax)
                    continue;   
            }

            foreach ($a as $key => $o) {
                if (end(array_keys($a)) == $key) {
                    $aux = '';
                } else {
                    $aux = ' - ';
                }

                echo $o . $aux;    
            }
            echo '<br />';
        }
    }

Only works with a single number

    if (in_array(14, $a)) {
        continue;
    }

E.g:

    <?= genNumbers(1, 25, 15, 100, 201, 201) ?>

This example continues returning values with 14 and 17. Like:

  1. 2 - 5 - 6 - 7 - 9 - 11 - 13 - 14 - 16 - 17 - 18 - 19 - 21 - 22 - 25
  2. 1 - 3 - 6 - 7 - 8 - 11 - 13 - 15 - 17 - 18 - 20 - 21 - 22 - 23 - 25
  3. 1 - 3 - 5 - 6 - 8 - 11 - 12 - 15 - 17 - 19 - 20 - 21 - 22 - 24 - 25
  4. 2 - 3 - 5 - 8 - 10 - 12 - 15 - 16 - 18 - 19 - 20 - 22 - 23 - 24 - 25
  5. 3 - 4 - 7 - 8 - 9 - 10 - 13 - 14 - 15 - 17 - 20 - 21 - 23 - 24 - 25

What is wrong? Thx!

Upvotes: 1

Views: 399

Answers (3)

bazeblackwood
bazeblackwood

Reputation: 1204

If you want to check that any of the values in your array meet the predicate, you can use this implementation of array_some:

function array_some(callable $callback, array $arr) {
  foreach ($arr as $element) {
    if ($callback($element)) {
      return TRUE;
    }
  }
  return FALSE;
}

Here's an example of how this might work using an anonymous (callable) function as the first argument to array_some, then passing the array you want to check in the predicate with use

$x = array(14, 17);

$z = array(13, 17);

$a = array(14, 18, 19, 12);

if (array_some(function($e) use ($a) { 
    return in_array($e, $a); 
}, $x)) {
    echo "some element of \$x is in \$a\n";
} else {
    echo "no element of \$x is in \$a\n";
}

if (array_some(function($e) use ($a) { 
    return in_array($e, $a); 
}, $z)) {
    echo "some element of \$z is in \$a\n";
} else {
    echo "no element of \$z is in \$a\n";
}

As expected, the output is:

// => some element of $x is in $a
// => no element of $z is in $a

array_every and array_some implementation - kid-icarus on github

Upvotes: 0

somethinghere
somethinghere

Reputation: 17350

You are using the wrong function. To accomplish this, a quick look at php.net gives us this: http://php.net/manual/en/function.array-search.php - which, when you scroll down a bit, tells us that if you want to find all matching values, you should use array_keys with a search_value, so:

array_keys(haystack, needle)

The above will return an array of matching keys. Example:

$a = array(1,2,3,4);
$r = array_keys($a, 2);

// $r is now [1] (because the key of 1 contains the value 2)

You can also be type strict by passing it a third parameters as true.

Source: http://php.net/manual/en/function.array-keys.php

Upvotes: 0

Marc B
Marc B

Reputation: 360772

You're using in_array wrong. It doesn't treat the "needle" specially. It looks for exact copies of the needle in the haystack:

php > $foo = array(1,2,3);
php > var_dump(in_array(array(1,2),$foo));
bool(false)

php > $bar = array(array(1,2),array(2,3), array(3,4));
php > var_dump(in_array(array(1,2), $bar));
bool(true)

Therefore you can't use a single in_array call to check for the existence of MULTIPLE values.

Upvotes: 1

Related Questions