Home > Net >  Put specific item on top without sorting others in laravel collection
Put specific item on top without sorting others in laravel collection

Time:05-30

I have an ordered laravel collection and i need too put element with id = 20 on top, without sorting other elements. Is it possible to do with sortBy?

CodePudding user response:

You can try to use filter method

// Say $originalCollection is the response from the large request, with data from the database

$modifiedCollection = $originalCollection->filter(fn($item) => $item->id === 20)
    ->concat($originalCollection->filter(fn($item) => $item->id !== 20));

Or to be more intuitive you can use filter and reject methods

$modifiedCollection = $originalCollection->filter(fn($item) => $item->id === 20)
->concat($originalCollection->reject(fn($item) => $item->id === 20));

The $modifiedCollection will have record with id = 20 at the top and rest of the records will remain in the same order as in $originalCollection

CodePudding user response:

if you want to put a specific item at the top of the array, simply add it separately.

$type = ['20' => 'Select Type'] $your_sorted_array ;

Example:

$country = ['1' => 'Andorra']   Countries::orderby('nicename')->pluck('name', 'id')->toArray();

Edit 1:Given new information, the on way you could "manually" do this is by using a combination of unset and unshift AFTER the array is built from the collection.

$key_value = $country[20];
unset($country[20]);
array_unshift($country, $key_value );

CodePudding user response:

if your collection is not very large you can use combination of keyBy, pull and prepend methods

  $originalCollection = Model::hereYourBigQuery()->get()->keyBy('id');
  /*
    now collection will look like this
    {
      'id1' => objectWithId1,
      'id2' => objectWithId2,
      ...
      20  => objectWithId20,
      ...
    }
  */
  // pull takes off element by its key
  $toMakeFirst = $originalCollection->pull(20);
  // prepend adding item into begining of the collection
  // note that prepend will reindex collection so its keys will be set by default
  $originalCollection->prepend($toMakeFirst);

upd: if you want to stick with sort there is a way

  $collection = Model::yourBigQuery()->get();
  $sorted = $collection->sort(function($a, $b){return $a->id == 20 ? -1 : 1;})->values();

as said in docs method sort can take closure as argument and utilizes php uasort under the hood

  • Related