Athari / YaLinqo

Yet Another LINQ to Objects for PHP [Simplified BSD]
https://athari.github.io/YaLinqo
BSD 2-Clause "Simplified" License
441 stars 39 forks source link

Distinct returns incorrect indexes #45

Closed Flaminel closed 5 years ago

Flaminel commented 5 years ago

After using distinct() on a collection of ids, the indexes of those distinct ids are exactly the first index where the value is encountered. Normally, I think one would expect them to be from 0 to N-1 ( N being the number of distinct values ).

I just found out it's not only distinct. Returned result sets's indexes are the same ones from their previous collection.

Athari commented 5 years ago

Discarding indexes has the following problems:

  1. While you consider the behavior you propose obvious, others may have a different opinion.

  2. Indexes are discarded forever, you can't get them back once they're gone. On the other hand, the opposite operation (discarding indexes from the iterator with indexes returned from disctinct()) is just a matter of calling toList().

  3. Consistency between various method calls are lost: one method keeps keys, another discards, so you never know what to expect without checking documentation every time. Inconsistency in behavior leads to bugs and frustration.

  4. Under normal circumstances, keys from distinct() can be ignored by the code which works with the iterator. For example, just using foreach ($values as $v) discards them.

Overall, YaLinqo follows a simple rule: Indexes are never discarded, unless stated otherwise. If you need to discard keys, you need to do it explicitly by calling toList() or toListDeep(). If you want to keep using iterator instead of switching to plain old array, there's also toValues() method.

The only exception to the rule is the cycle() method. Without discrading of keys, it causes keys to be duplicated many times, making sequences nonsensical and hard to use (keys are supposed to be unique).