Обратный порядок коллекции Doctrine_Collection - PullRequest
11 голосов
/ 21 марта 2012

Я ищу чистый способ изменить порядок коллекции Doctrine_Collection. Я знаю, это звучит странно, поэтому позвольте мне объяснить мою (простую) цель: мне нужно отобразить запись x последний / самый новый , но я должен отобразить ее в обратном порядке: самый старый и т. Д.

Если неясно, вот пример: Допустим, у меня есть это в моей таблице (назовем это «пример»):

id      date
1       2012-01-21
2       2012-03-19
3       2012-02-21
4       2012-03-21

Пока что я сделал это:

Doctrine::getTable('Example')->createQuery('d')
    ->orderBy('date DESC')
    ->limit(3);

Что возвращает это

id      date
4       2012-03-21
2       2012-03-19
3       2012-02-21

Но я хочу это:

id      date
3       2012-02-21
2       2012-03-19
4       2012-03-21

Edit:

Я нашел решение для этого, используя промежуточный массив и используя для него array_reverse. Но это не выглядит хорошо: (

Вот код, который я написал:

    $query = Doctrine::getTable('Example')
            ->createQuery('e')
            ->orderBy('date DESC')
            ->limit(3)
        $collection = $query->execute();

        //Here is the dirty hack:
        $itemArray = array();
        foreach ($collection as $item) {
            $itemArray[] = $item;
        }
        $itemArray = array_reverse($itemArray);
        $orderedCollection = new Doctrine_Collection($doctrineClass);
        foreach($itemArray as $item) {
            $orderedCollection->add($item);
        }
        //OrderedCollection is OK but... come on! There must be a cleaner way to do it

Редактировать 2: ответ от @Adam Kiss

        $query = Doctrine::getTable('Example')
            ->createQuery('e')
            ->orderBy('date DESC')
            ->limit(3)
        $collection = $query->execute();

        //Here is the **lovely** hack:
        $orderedCollection = new Doctrine_Collection('Example');
        for ($i=($collection->count() - 1); $i>=0;$i--) {
            $orderedCollection->add($collection->get($i));
        }

Ответы [ 7 ]

15 голосов
/ 21 марта 2012

без промежуточного массива:

for ($i = $collection->count(); $i > 0; $i--) {
    $orderedCollection->add($collection->get($i));
}

Надеюсь, хороший ответ:

Вы можете экспортировать коллекцию в массив и перевернуть ее

$query = Doctrine::getTable('Example')
         ->createQuery('e')
         ->orderBy('date DESC')
         ->limit(3)
$collection = $query->execute();
$collection = array_reverse($collection->toArray());

Старый (неправильный) ответ:

Может быть, вы должны использовать

Doctrine::getTable('Example')->createQuery('d')
  ->orderBy('date ASC')
  ->limit(3);
5 голосов
/ 24 марта 2012

Если вы не хотите использовать какую-либо специальную функциональность коллекции, просто переберите элементы в обратном порядке (без каких-либо накладных расходов), вы можете сделать это довольно просто, например:

/** @var $results Doctrine_Collection this is your result collection */
$iterator = $results->getIterator();
$item = end($iterator);

do {
  var_dump($item);
} while ($item = prev($iterator));
5 голосов
/ 23 марта 2012

Похоже, вам нужно либо настроить Doctrine_collection , чтобы обеспечить что-то похожее на array_reverse в вашем классе коллекции, либо использовать какой-то хакерский подход, например:

0 голосов
/ 30 января 2018

Для Доктрины \ ORM \ PersistentCollection

/** @var Doctrine\ORM\PersistentCollection $posts */
$posts = $category->getPosts();
for ($i = $posts->count()-1; $i >= 0; $i--) {
    $post = $posts->offsetGet($i);
    // ... do some logic
}
0 голосов
/ 10 марта 2015

Судя по всему, просто удалите "DESC" из заказа. Запрос возвращается в порядке убывания даты в точности так, как он указан, и вы хотите, чтобы он был в порядке возрастания.

0 голосов
/ 13 февраля 2015

Если вам нужен объект ArrayCollection, другое решение этого вопроса, которое расширяет ответ @ adam-kiss, - это использовать возвращенное значение array_reverse для создания нового объекта ArrayCollection, который уменьшает потребность вfor петля.

use Doctrine\Common\Collections\ArrayCollection;

$query = Doctrine::getTable('Example')
    ->createQuery('e')
    ->orderBy('date DESC')
    ->limit(3)
;
$collection = $query->execute();
$orderedCollection = new ArrayCollection(array_reverse($collection->toArray()));
0 голосов
/ 28 марта 2012

возможно, вам следует использовать вот так

     ->orderBy('date', 'DESC')

, потому что в этой документации http://docs.doctrine -project.org / projects / doctrine-orm / en / 2.0.x / reference / query-builder.html для подписи orderby требуется ASC / DESC в качестве второго параметра

      public function orderBy($sort = null, $order = null);
...