Framework: [Solved] toArray() does not preserve Collection order

Created on 14 Oct 2013  路  8Comments  路  Source: laravel/framework

It seems that if I use the sort() method on a Collection (from Eloquent) and then I return it as array/json the Collection order is lost.

$models = MyModel::where('name', $name)->get();
$models->sort(function($a, $b) {
    return Version::compare($a->version, b->version);
});
return $models->toArray();

I'm I doing something wrong?
Thx.

Most helpful comment

I think it would do so when you explicitly send array_values to discard the keys, or perhaps $collection->values()->toArray() but that would modify the collection (which I don't think is a problem, but something to be aware of)

All 8 comments

Out of curiosity, Is $models in the correct order before you call toArray()?

Yes, it is.
The Collection sort method uses uasort internally. So the resulting internal array is in the correct order and preserves the ids as indexes. Let's say you would dd($models) or return a $models->first() you will get what you expect.

I just checked this on the latest and I can't appear to replicate the issue. Model is in the correct order before and after calling toArray(). Not sure where this would be going wrong.

Ok I feel kind of stupid. The method does work as expected. Sorry.
Chrome was "being smart" and reordered the json output. But looking at the raw/real json, the elements are in the correct order.

By the way, is there an easy way to return a 'real' array in JSON format? In fact, Chrome does have a point here, simply returning toJSON() from my collection gives me an object of objects, not a proper array. Ordering is therefore not important.

I think it would do so when you explicitly send array_values to discard the keys, or perhaps $collection->values()->toArray() but that would modify the collection (which I don't think is a problem, but something to be aware of)

Sweet, it would do it for now.
Thank you very much!

being quite long.. But is helpful. thanks

For me as well calling

return $this->response->withJson( [
                'code' => 200,
                'data' => $mySortedCollection->values()
            ] );

did it... :-) Thanks a lot @JoostK .

Was this page helpful?
0 / 5 - 0 ratings