Измените порядок набора доктрин в обратном порядке


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

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

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

Изменить:

Я нашел решение этой проблемы, используя промежуточный массив и используя для него 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));
        }
Author: haltabush, 2012-03-21

7 answers

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

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);
 12
Author: Adam Kiss, 2012-03-26 08:35:49

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

$keys = array_reverse($collection->getKeys());
foreach ($keys as $key) {
    $object = $collection->get($key);
}
 5
Author: dbrumann, 2012-03-23 16:20:02

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

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

do {
  var_dump($item);
} while ($item = prev($iterator));
 5
Author: 1ed, 2012-03-23 20:59:19

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

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

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

      public function orderBy($sort = null, $order = null);
 0
Author: Ekrem, 2012-03-27 21:51:46

Если вам нужен объект 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
Author: george, 2015-02-13 15:20:05

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

 0
Author: Chris, 2015-03-10 09:59:54

Для доктрины\ИЛИ\постоянной коллекции

/** @var Doctrine\ORM\PersistentCollection $posts */
$posts = $category->getPosts();
for ($i = $posts->count()-1; $i >= 0; $i--) {
    $post = $posts->offsetGet($i);
    // ... do some logic
}
 0
Author: Martin Belobrad, 2018-01-30 16:28:08