Re: ARRAY_UNIQUE_IDENTICAL option
| From: | tyson andre | Date: | Mon, 07 Nov 2022 22:45:34 +0000 |
| Subject: | Re: ARRAY_UNIQUE_IDENTICAL option | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-118983@lists.php.net to get a copy of this message | ||
Hi Levi Morrison,
> A bit off topic, but not entirely:
>
> In my opinion, adding another flag isn't the _real_ fix. Any function
> which does comparisons should take a callable for users to provide any
> comparison they wish. An iteratively better API would be:
>
> function array_unique<T>(list<T> $array, callable(T $a, T $b): int
> $comparator);
>
> Of course, there are other things like instead of using int for
>
0,
> -1, 1, we could have used an
> enum but we don't have one today. I
> just mean the core idea of taking callable is better than mucking
> around with flags while also allowing for custom comparison. Note that
> it doesn't necessarily prevent optimizations either. For instance, if
> they had passed php_compare or some function which represents
> `$a
> <=> $b`, we could identify that just as we identify a specific flag
> and take an optimized pass.
1. Calling php functions from C is fairly slow. Sorting compared to hash maps is also slow
If we did want a specialized implementation for user-provided
equality criteria, ?callable(T $a): U $iteratee = null would seems more practical to me
(Calling a function n times rather than n log n times would be faster,
and this would work even for cases such as
[$obj->nonObjectField1, $obj->field2->toNormalizedRepresentation()] instead of
using a comparator in most cases
(by putting both arrays into the internal hash map)
(same approach as https://lodash.com/docs/#uniqBy)
2. <=> isn't a stable order for int/string/float (etc) in various ways,
so some comparators would have issues and return duplicates.
It's possible to implement stable comparisons, but I don't really expect enthusiasm for
that
https://github.com/TysonAndre/pecl-teds/#stable-comparison
3. I expect a majority of cases could use the ARRAY_UNIQUE_IDENTICAL directly.
(or use that on array_map()ped values to find the keys of the original array to use)
So requiring the use of $comparator would result in longer code and more possible sources of bugs
(e.g. a comparator returning $a - $b might overflow/underflow int if users
don't realize <=> should be used)
Thanks,
Tyson