Php 颠倒集合的顺序
我正在寻找一个干净的方法来颠倒一个集合的顺序。 我知道这听起来很奇怪,所以让我解释一下我的(简单的)目标:我需要显示x最新/最新的记录,但我必须按相反的顺序显示:最早的第一个,等等 如果不清楚,下面是一个例子: 假设我的表中有这个(我们称之为“示例”): 到目前为止,我已经做到了:Php 颠倒集合的顺序,php,doctrine,symfony-1.4,Php,Doctrine,Symfony 1.4,我正在寻找一个干净的方法来颠倒一个集合的顺序。 我知道这听起来很奇怪,所以让我解释一下我的(简单的)目标:我需要显示x最新/最新的记录,但我必须按相反的顺序显示:最早的第一个,等等 如果不清楚,下面是一个例子: 假设我的表中有这个(我们称之为“示例”): 到目前为止,我已经做到了: Doctrine::getTable('Example')->createQuery('d') ->orderBy('date DESC') ->limit(3); 哪个返回那个
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\u 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));
}
没有中间数组:
希望答案是好的:
您可以将集合导出到数组并将其反转
$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);
看起来您要么必须在collection类中提供类似于
array\u reverse
的内容,要么使用一些黑客方法,如以下所示:
$keys = array_reverse($collection->getKeys());
foreach ($keys as $key) {
$object = $collection->get($key);
}
如果您不想使用任何特殊的集合功能,只需按相反的顺序迭代元素(无任何开销),您就可以很容易地做到这一点:
/** @var $results Doctrine_Collection this is your result collection */
$iterator = $results->getIterator();
$item = end($iterator);
do {
var_dump($item);
} while ($item = prev($iterator));
也许你应该这样用
->orderBy('date', 'DESC')
因为在这个文档中
orderby的签名要求ASC/DESC作为第二个参数
public function orderBy($sort = null, $order = null);
如果您想要一个
ArrayCollection
对象,另一个解决方案是使用array\u 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()));
从外观上看,只需从orderby中删除“DESC”即可。查询返回的日期降序与所告知的完全相同,并且您希望它以升序返回。For Doctrine\ORM\PersistentCollection 这对我有用。 条令版本:1.2
$collection = //make doctrine collection;
$reversed_array = array_reverse($collection->toArray());
$collection->fromArray($reversed_array);
不,如果我这样做,我就不会有3条最新的记录,而是3条最老的记录。我也考虑过,但问题是toArray也会将Doctrine_记录转换为数组…我绝对不希望:)祝贺你,你的最终解决方案是更干净的(在我看来)。你只是在for循环中有一个小的输入错误$我应该一直到>0,而不是>0=0@haltabush哦,是的,我会解决:)循环
的另一个问题是count
返回项目总数,而不是最后一个项目索引。因此,循环计数将始终是上一个索引的+1
。例如:count(['a'])=1,其中索引应为0
。因此,要以相反的顺序迭代集合中的所有可用项,它需要是$i=$collection->count()-1$i>=0$我--
但是我建议利用它来确保对键进行预期的迭代。这很好:)但是,正如您所猜测的,我的查询在一个模型中,我实际上想要返回一个Doctrine_集合的实例。我可能会混合使用您的解决方案和Mahok的(如果没有其他人有更好的主意),您可以返回一个集合(因为$results
变量是一个集合),并在视图中使用它(可能是为了可重用性的一部分)……的确,在视图中这样做有点奇怪:)haltabush是正确的,不应该在视图中迭代集合,除非在控制器中对其进行本地化,然后将其传递给视图。确定,然后在模型中执行此操作return$results->setData(array_reverse($results->getData(),true))代码>嗯,是的,但这也不是什么大不了的事。我一直用的是这种方式,它也有效;当您有多个orderBy子句时,也就不那么容易混淆了,我看到了。。。如果你不介意在条令中使用原始sql,这可能有助于选择*从(选择*从<代码>示例代码>按日期排序描述限制3)到按日期排序2 ASCI我不介意原始sql,抱歉:)我也考虑过这一点。顺便说一句,被接受的答案对我来说没问题。我只是忘了结束悬赏(我认为这是自动的),我想要一个条令库。也许我可以给它一个数组集合作为一个setter,但我不确定。
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()));
/** @var Doctrine\ORM\PersistentCollection $posts */
$posts = $category->getPosts();
for ($i = $posts->count()-1; $i >= 0; $i--) {
$post = $posts->offsetGet($i);
// ... do some logic
}
$collection = //make doctrine collection;
$reversed_array = array_reverse($collection->toArray());
$collection->fromArray($reversed_array);
use Doctrine\Common\Collections\Criteria;
...
$criteria = Criteria::create();
$criteria->orderBy(['id' => 'DESC']);
return $this->objections->matching($criteria);