Я пытаюсь отсортировать 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));



Похоже, это хороший вариант использования Критерии доктрины. Они позволяют фильтровать/сортировать 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));
}
Для сущности сделайте следующее: добавьте к свойству аннотацию OrderBy.
/**
* @OneToMany(targetEntity = "Course")
* @OrderBy({"live": "ASC"})
*/
private $courses;