Сортировка Doctrine ArrayCollection по определенному пользовательскому полю

Я пытаюсь отсортировать 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));
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
2
0
3 435
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Похоже, это хороший вариант использования Критерии доктрины. Они позволяют фильтровать/сортировать 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;

Другие вопросы по теме