|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2020-11-10 01:21 UTC] gilperon at gmail dot com
Description:
------------
Run the test script. It has 2 arrays in such a way that only the key `4` appears on both. Using `array_intersect_ukey` does not return `4`, instead it returns `array(0) {}`. Using `array_intersect_key` works perfectly. I also realized there is a bug in the implementation of this function, because if you run the test script it will show you this:
|4|6|DIFFERENT
|8|6|DIFFERENT
|4|8|DIFFERENT
|3|4|DIFFERENT
|5|4|DIFFERENT
|3|5|DIFFERENT
|6|4|DIFFERENT
|6|5|DIFFERENT
|6|3|DIFFERENT
It shouldnt be comparing 8 with 6 because these keys only appear on the 1st array and these keys shouldnt be compared at all. You can clearly see that this function, instead of comparing each key of the first array with each key of the second array, it's comparing the keys from the first array WITH ITSELF and then comparing the keys of the second array ITSELF (line |3|5|) and only then comparing the keys of both arrays together (but for some reason it misses the |4|4|).
I know that in my simple use case I should be using `array_intersect_key` but I really need `array_intersect_ukey` to work properly because I have a much more complex use case for it.
Test script:
---------------
<?php
$array1 = array(4 => true, 6 => true, 8 => true);
$array2 = array(3 => true, 4 => true, 5 => true);
var_dump(array_intersect_ukey(
$array1,
$array2,
function ($key1, $key2) {
echo "|" . $key1 . "|" . $key2 . "|";
if ($key1 === $key2) {
echo "EQUAL\n";
return 0;
}
else{
echo "DIFFERENT\n";
return 1;
}
}
));
?>
Expected result:
----------------
It should only show the element 4, which is present in both arrays.
Actual result:
--------------
Nothing is returned from the intersection.
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 14:00:01 2025 UTC |
Changing the code: echo "DIFFERENT\n"; return 1; to: echo "DIFFERENT\n"; return $key2 - $key1; Makes your code work. It looks like this code may be sorting the arrays first, and sorting algorithms need to be stable: https://www.geeksforgeeks.org/stability-in-sorting-algorithms/ That's an educated guess. If it is that, it's a docs problem as stability probably should be mentioned.cmb@php.net in my opinion as a PHP user/programmer for the last 10 years which uses a lot the documentation, I think that we can have at least 2 alternatives: 1) make it clear in the documentation that the `callback` function will not only be called when the intersection is being done/compared, but also in the `sort` phase (which, to me, makes completely no sense, since the intent of the callback is exactly to make a custom comparator between keys, not to make a custom "sorter"); 2) allow a parameter to be added to the function `array_intersect_ukey` named DONT_CALL_MY_CALLBACK_ON_SORT_PHASE which the user can set to true/false (again, to me makes completely no sense calling the custom callback function in the sort phase, because it's not intuitive and not expected by the user/programmer). If you guys still decide to keep calling the callback function during the sort phase, I think there should be a third parameter in the callback function `function ($key1, $key2, $phase)` which tells the user whether it's in the sort or intersect phase, and the user can do something like: function ($key1, $key2, $phase) { if ($phase === 'sort') { return $key2 - $key1; } else if ($phase === 'intersect') { //here comes the actual intersect callback function, where the user can do lots of complicated math, stuff... and return TRUE or FALSE if the intersection was succesfull or not. } }