按特定的自定义字段对 Doctrine ArrayCollection 进行排序

crm*_*cco 5 arrays sorting doctrine symfony php-7.2

ArrayCollection我正在尝试按特定字段进行排序。这ArrayCollection是一系列课程。在Course实体中有一个调用的方法isLive,它返回一个布尔值。

我想对此集合进行排序,以将“实时”课程放在数组的开头,这样这就是trueisLive调用返回的课程。

这是我目前拥有的代码,但数组中的第一个条目$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));
Run Code Online (Sandbox Code Playgroud)

rom*_*gon 7

它看起来是Doctrine Criteria的一个很好的用例。它们允许对 ArrayCollections 进行过滤/排序,如果集合已加载,则可以在内存中进行过滤/排序,也可以通过在下次从数据库加载集合时添加WHERE/ SQL 子句来过滤/排序。ORDER BY所以这非常优化!

代码应该看起来像这样,假设live后面有一个字段isLive()

$criteria = Criteria::create()
    ->orderBy(["live" => Criteria::DESC])
;

$sorted = $this->courses->matching($criteria);
Run Code Online (Sandbox Code Playgroud)


crm*_*cco 1

我使用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));
}
Run Code Online (Sandbox Code Playgroud)