Reputation: 3758
I have a Laravel Collection with items in it. Assuming the items are in the collection in numerical order.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
If for example I have items 1-15 laid out like the following in the View (the number of rows can change but number of columns will always stay the same):
1 4 7 10 13
2 5 8 11 14
3 6 9 12 15
*think of each column as a different type of mammal (cats, dogs, birds, etc.)
Is there a way to easily reorder the items like the following within the Collection?
1 4 7 10 13 2 5 8 11 14 3 6 9 12 15
So in the View it would now look like this:
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
*The View that I talk about is for illustrative purposes only. I only require changes to the Collection in the manner stated above. Populating the collection perfectly from the beginning would be the optimal answer but I can't figure out a way to do so.
Upvotes: 2
Views: 8226
Reputation: 81187
While not discussing whether it makes sense to order the collection or better do it in your SQL query, this is the answer for your generic question (adjust for your specific needs if necessary):
1 compare function:
/**
* Sort the array in groups.
*
* @param mixed $previous
* @param mixed $next
* @param integer $groups
* @return bool
*/
function sortInGroups($previous, $next, $groups = 3)
{
// If equal then return 0
if ($previous == $next) return 0;
// Otherwise check the modulus in order to
// group the items. However if modulus is zero,
// then shift group to the very end of final array.
$prev = ($previous%$groups) ?: $groups;
$nxt = ($next%$groups) ?: $groups;
// If moduli are equal then items are
// in the same group so compare the items.
if ($prev == $nxt)
{
return ($previous < $next) ? -1 : 1;
}
// Otherwise compare the moduli in order to group the items.
return ($prev < $nxt) ? -1 : 1;
}
2 sort the collection by whatever property you want (id for example):
$collection = SomeModel::take(15)->get(); // or Support\Collection
$collection->lists('id'); // [1,2,3,4,... 15]
$collection->sort(function ($prev, $next) {
return sortInGroups($prev->id, $next->id, $cols = 5);
});
$collection->lists('id'); // [1,4,7,10,13,2,5,8,11,14,3,6,9,12,15]
Upvotes: 1
Reputation: 152900
I don't think it is perfect but it works.
This code assumes $collection
is the collection you want to reorder
$arrayCollection = array();
$numberOfColumns = 5; // adjust this value to change number of columns
$numberOfRows = $collection->count() / $numberOfColumns
foreach($collection as $index => $model){
$column = floor($index / $numberOfRows);
$newIndex = (int)($index % $numberOfRows) * $numberOfColumns + $column;
$arrayCollection[$newIndex] = $model;
}
ksort($arrayCollection); // sort collection by key
$collection = new Collection($arrayCollection); // make new collection with reordered models
Upvotes: 2
Reputation: 1858
You can manually order by a column.
If these are the id 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Then you can use order by FIELD(id, 1, 4, 7, 10, 13, 2, 5, 8, 11, 14, 3, 6, 9, 12, 15);
Upvotes: 0
Reputation: 24661
Why should you reorder the collection? Sounds to me you want something like this:
@foreach($collection as $item)
<div class="collection-item">{{ $item->value }}</div>
@endforeach
Then apply CSS styles in order to have each of the collection-item
divs display inline rather than as block elements.
If you truly want a reordered collection, then specify the order you want when you fill the collection:
Model::all()->orderBy('field', 'desc')->get();
Upvotes: 1