#arrays #symfony #sorting #doctrine #php-7.2
#массивы #symfony #сортировка #doctrine #php-7.2
Вопрос:
Я пытаюсь отсортировать 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));
Ответ №1:
Это выглядит как хороший вариант использования для критериев Doctrine. Они позволяют фильтровать / сортировать ArrayCollections либо в памяти, если коллекция уже загружена, либо путем добавления предложения WHERE
/ ORDER BY
SQL при следующей загрузке коллекции из базы данных. Итак, это довольно оптимизировано!
Код должен выглядеть примерно так, предполагая, что за live
вами стоит isLive()
поле:
$criteria = Criteria::create()
->orderBy(["live" => Criteria::DESC])
;
$sorted = $this->courses->matching($criteria);
Ответ №2:
Для объекта сделайте это: добавьте аннотацию OrderBy к свойству.
/**
* @OneToMany(targetEntity="Course")
* @OrderBy({"live": "ASC"})
*/
private $courses;
Ответ №3:
Я пришел к решению с использованием 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));
}