2

I am trying to count the matches between expected and actual in a PHP array, I have this...

$array = array(
    "item" => array(
        'expected' => array(
            '1' => 25,
            '2' => 4,
            '3' => 4,
        ),
        'color' => 'red',
        'actual' => array(
            '1' => 25,
            '2' => 4,
            '3' => 3,
        ),
    ),
);

foreach ($array as $key => $arrayItem) {

    $matches = array (
        'matches'  => count ( array_intersect ( $arrayItem['expected'], $arrayItem['actual'] ) ),
    );

}

echo "Matches = " . $matches['matches'];

I am expecting this to return 2 but it is actually returning 3. If I change the values like in the example below then it does work...

$array = array(
    "item" => array(
        'expected' => array(
            '1' => 25,
            '2' => 84,
            '3' => 4,
        ),
        'color' => 'red',
        'actual' => array(
            '1' => 25,
            '2' => 84,
            '3' => 3,
        ),
    ),
);

foreach ($array as $key => $arrayItem) {

    $matches = array (
        'matches'  => count ( array_intersect ( $arrayItem['expected'], $arrayItem['actual'] ) ),
    );

}

echo "Matches = " . $matches['matches'];

Anyone any ideas why the top version is not giving me the expected result?

Razneesh
  • 1,147
  • 3
  • 13
  • 29
fightstarr20
  • 11,682
  • 40
  • 154
  • 278

3 Answers3

3

Because it returns an array containing all values in array1 whose values exist in all of the parameters.

array_intersect(array $array1, array $array2[, array $... ]): array

https://www.php.net/manual/en/function.array-intersect.php

Maybe you can see it clearly from this perspective:

var_dump(array_intersect([25, 4, 4, 4], [25, 4, 3])); // [25, 4, 4, 4] 
// because the number `4` is in the second array!

var_dump(array_intersect([25, 4, 3], [25, 4, 4, 4])); // [25, 4]
Chemaclass
  • 1,933
  • 19
  • 24
2

The count is actually correct.

It doesn't happen in your second example because you use the numbers 84 and 4, but essentially here are the matches:

$arrayItem['expected'][1] matches with $arrayItem['actual'][1] (25 and 25)

$arrayItem['expected'][2] matches with $arrayItem['actual'][2] (4 and 4)

$arrayItem['expected'][3] matches with $arrayItem['actual'][2] (4 and 4)

The count of 3 is correct.


You can test this by changing your code to the following:

$matches = array(
    'matches' => array_intersect ($arrayItem['expected'], $arrayItem['actual'])
);

var_dump($matches);

Here you'll see this output:

array(1) {
    ["matches"] => array(3) {
        [1]=> int(25) 
        [2]=> int(4) 
        [3]=> int(4)
    }
}
Mark
  • 1,852
  • 3
  • 18
  • 31
  • 2
    _$arrayItem['expected'][2] and $arrayItem['expected'][3] are counting as a match_ Not true. [See demo](https://3v4l.org/8JjHO) – nice_dev Feb 13 '20 at 10:24
  • 1
    Number `4` is met __twice__ in `expected`, that's why `4` is __checked__ twice in `actual` and gets a match of course. __Nothing is matched with itself__. – u_mulder Feb 13 '20 at 10:27
-1

it returns 2

<?php

 $array = array(
    "item" => array(
        'expected' => array(
            '1' => 25,
            '2' => 84,
            '3' => 4,
        ),
        'color' => 'red',
        'actual' => array(
            '1' => 25,
            '2' => 84,
            '3' => 3,
        ),
    ),
);

echo count(array_intersect($array['item']['expected'],$array['item']['actual']));
John Doe
  • 85
  • 1
  • 8