Novactive / NovaCollection

Collection implementation that wraps regular PHP arrays.
MIT License
9 stars 3 forks source link

Positive and negative numeric offsets for collections #7

Open nozavroni opened 7 years ago

nozavroni commented 7 years ago

What do you think about allowing numeric offsets for all collections, even if they aren't indexed numerically? Sometimes I have found it is useful to get the, for example, "5th" item in the collection. If the collection were indexed numerically I could do simply:

$fifth = $coll[4];

If the collection isn't indexed numerically, I either have to loop over the collection to get the fifth item:

$i =0;
foreach ($coll as $item) {
    if ($i++ == 4) {
        $fifth = $item;
    }
}

Or, we can add a getValues() or just values(), which would re-index the collection numerically.

$fifth = $coll->values()->get(4);

Finally, we get to my proposal. I'm wondering if it would be counter-intuitive to allow numeric indexing for even non-numerically indexed collections:

$coll = new Collection([0=>'one',1=>'two',2=>'three',3=>'four',4=>'five',5=>'six']);
$fifth = $coll[4];
// or...
$fifth = $coll->offsetGet(4);
// Collection::get() would still return null because it is only for getting by ACTUAL index... no magic
$fifth = $coll->get(4); // returns null

Additionally, I would like for negative offsets to work in the same way. If you passed in a negative numeric offset, it would begin counting from the end of the collection.

$coll = new Collection([0=>'one',1=>'two',2=>'three',3=>'four',4=>'five',5=>'six']);
$fourthfromlast = $coll[-4]; // returns 'three'
// or...
$fourthfromlast = $coll->offsetGet(-4); // returns 'three'
// Collection::get() would still return null because it is only for getting by ACTUAL index... no magic
$fourthfromlast = $coll->get(-4); // returns null

Interested to get your opinion on this. My only issue with it is that if a collection is indexed numerically but in the WRONG order, this may result in some confusion. For example, how would you deal with this?

$coll = new Collection([4=>'one',-2=>'two',1=>'three',0=>'four',14=>'five',105=>'six']);

I suppose you could check that the numeric index being requested already exists in the collection, and if not, only THEN you would return the Nth item in the collection. But I don't like the unpredictability of this... @Plopix what do you think?

nozavroni commented 7 years ago

By the way this is part of the reason I had created a special type of collection called a Sequence in my personal collections library. It allowed me to have a collection with an absolutely predictable indexing scheme.

Plopix commented 7 years ago

I think that I like the -4, it reminds me what we can do with substr etc.. But I agree, making a difference between get and offsetGet sounds risky to me. Why not an indexOf that would work for both ?

nozavroni commented 7 years ago

indexOf tells you the index of a value... not the same

Plopix commented 7 years ago

atIndex ?

anaelChardan commented 7 years ago

Why not just index($at) ?