0

Here is what I'm trying to do : I have an array of strings (containing id) and an array of objects. I'm trying to get all the ids listed in the first array that are not in the object array.

Here is what I tried $ids is the array of strings and $features is the array of objects :

array_udiff($ids, $features, function($a, $b){
    return strcmp($a, $b->getIdFeature());
});

but I get an error

Fatal : Call to a member function getIdFeature() on string

I thought ids goes in $a and features in $b, this is not the case ? Is there a way to force this ?

ᴄʀᴏᴢᴇᴛ
  • 2,939
  • 26
  • 44
  • 3
    I don't think you can force it. You can check the type of the arguments, and based on that change them like this: `if (is_object($a)) $a = $a->getIdFeature();` and the same for `$b`. – KIKO Software Oct 05 '17 at 08:35
  • You can check variable types inside the function using `instanceof` and `is_string` and do the comparison according to it. – Roman Hocke Oct 05 '17 at 08:39
  • 1
    It makes sense that it would **not** have `$a` from the first array and `$b` from the second array. What you essentially have in the function is a comparator so if you sort both arrays based on the comparator (in `O(n logn)` time) you can then get the diff in `O(n)` time in a *sort-join* manner. If it was just pairwise comparisons it would be `O(n^2)` so I suggest you treat your callback as the general comparator function which works for the comnbined first and second array. – apokryfos Oct 05 '17 at 08:45
  • @apokryfos Ok I understand. I'll do as suggested by *KIKO software* – ᴄʀᴏᴢᴇᴛ Oct 05 '17 at 08:50
  • Possible duplicate of [How to work around array\_udiff's type coercion](https://stackoverflow.com/questions/56124509/how-to-work-around-array-udiffs-type-coercion) – Arne May 15 '19 at 06:46

1 Answers1

0

In the callback, use a ternary condition to access the comparable data.

array_udiff(
    $ids,
    $features,
    fn($a, $b) => 
        is_string($a) ? $a : $a->getIdFeature()
        <=>
        is_string($b) ? $b : $b->getIdFeature()
);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136