我试图按特定字段对ArrayCollection
进行排序。 ArrayCollection
是一系列课程。在Course
实体中有一个名为isLive
的方法,它返回一个布尔值。
我想对这个集合进行排序,以便在数组的开头有“实时”课程,这样就是从true
调用返回isLive
的课程。
这是我目前的代码,但$sorted
数组中的第一个条目是非实时课程。
$iterator = $this->courses->getIterator();
$iterator->uasort(function ($a, $b) {
if ($a->isLive() == $b->isLive()) {
return 0;
}
return ($a->isLive() < $b->isLive()) ? -1 : 1;
});
$sorted = new ArrayCollection(iterator_to_array($iterator));
它看起来像Doctrine Criteria的一个很好的用例。如果集合已经加载,它们允许在内存中对ArrayCollections进行过滤/排序,方法是在下次从数据库加载集合时添加WHERE
/ ORDER BY
SQL子句。所以这非常优化!
代码应该看起来像这样,假设你在live
后面有一个isLive()
字段:
$criteria = Criteria::create()
->orderBy(["live" => Criteria::DESC])
;
$sorted = $this->courses->matching($criteria);
我得到了一个使用uasort
和array_search
的解决方案,如下所示:
/**
* @return ArrayCollection
*/
public function getCoursesSortedByLive(): ArrayCollection
{
$coursesIterator = $this->courses->getIterator();
$sortOrder = [true];
$coursesIterator->uasort(function ($a, $b) use ($sortOrder) {
return array_search($a->isLive(), $sortOrder) - array_search($b->isLive(), $sortOrder);
});
return new ArrayCollection(iterator_to_array($sitesIterator));
}