2013-08-26 6 views
2

У меня есть объект «Post», доступ к которому осуществляется через контейнер IOC. Различные ошибки говорят мне, что тип этого объекта заканчивается как «Collection», который реализует несколько интерфейсов, включая IteratorAggregate и ArrayAccess.PHP Iterator Пользовательский порядок сортировки (Laravel 4)

Я хочу, чтобы отобразить определенного пользователь группы должностей в соответствии с определенным порядком, например .:

$desired=array("69","63","70");//these represent post id's 

Просто сортировками массива в этой манере кажется сложным, но я хочу, чтобы отсортировать мою коллекцию. Я изучал различные комбинации usort(), uksort(), sortBy(), ELEQUENT sort() ..., но наиболее очевидные решения приводят к таким заказам, как 3,2,1 или 1,2,3, а не 2, 1,3.

Ближайший я добрался до этой цели принести те, которые я хочу,

//BlogController 
private function myposts($desired){ 
    $posts=$this->post->whereIn('id',$desired)->get(); 
    ... 

«преобразовать» объект коллекции в массив,

$posts=$posts->toArray(); 

и обработать массив с пользовательские функции: source

function sortArrayByArray($array,$orderArray) { 
    $ordered = array(); 
    foreach($orderArray as $key) { 
     if(array_key_exists($key,$array)) { 
      $ordered[$key] = $array[$key]; 
      unset($array[$key]); 
     } 
    } 
    return $ordered + $array; 
} 
$sorted=sortArrayByArray($array1,$desired); 

Я тогда vardump массив в корбанка ect, но поскольку он теперь является массивом, я не могу получить доступ к объекту $ posts в моем представлении. Можно ли преобразовать массив обратно в объект post?

Весь этот подход все равно выглядит расточительным, превращаясь в массив и обратно ... не так ли? Есть ли более простой способ сортировки содержимого «Коллекция»?

Это немного лучше, возможно, (родная функция PHP):

array_multisort($desired,$posts,SORT_STRING); 
//only works with string keys 
//$desire=(1,2,3) will not work! 

Опять же, это работает для массивов, но попытка непосредственно на «должность» объект терпит неудачу ...

Наконец , я обнаружил, используя Presenter: https://github.com/robclancy/presenter#array-usage, который работает в виде, после того, как один из выше будет завершена в контроллере:

@foreach($posts as $post) 
<?php $post=new PostPresenter($post) ?> 
{{View::make('site.post.article')->with(compact('post'))}} 
@endforeach 

Это, наконец, работает, но до сих пор плата Это долгий путь. Есть ли лучший способ выполнить эту задачу? Проблемы с производительностью или лучшие практики с одним методом по сравнению с другим? Заранее благодарим всех, кто может помочь.

ответ

2

Вы можете использовать собственный метод Collections sort и передать его в обратном вызове. Обратный вызов сравнивает каждые два значения в вашей коллекции, сообщает метод сортировки, который является «более высоким». Затем сортировка сортирует их соответственно. Если вам нужен определенный порядок значений, вы просто создаете сопоставление и сортируете по нему. Для получения дополнительной информации ознакомьтесь uasort

$posts->sort(function($a, $b){ 
    $desired=array("69" => 0,"63" => 1,"70" =>2); 
    if(!array_key_exists($a,$desired) || !array_key_exists($b,$desired) || $a == $b){ 
     return 0 
    } 
    else{ 
     return ($desired[$a] < $desired[$b]) ? -1 : 1; 
    } 
}); 
+0

Я собираюсь попробовать этот метод, но я должен потяните мой «заказ» с использованием() из-за закрытия. –

1

В качестве альтернативы @ ответ Тиму, вы можете переназначить отсортированный массив на новый объект Collection:

$postsArray = $this->posts->toArray(); 

// Do some sorting/processing, then: 

$newCollection = new \Illuminate\Database\Eloquent\Collection($postsArray); 
+0

Когда я пытаюсь это сделать, а затем попытаюсь выполнить цикл $ postsArray и ссылку $ post-> name или любой атрибут элемента коллекции, я получаю ошибку: «Пытаться получить свойство не-объекта» – phirschybar

Смежные вопросы