php “usort”一个原则\公共\集合\数组集合?

7gs2gvoe  于 2022-12-25  发布在  PHP
关注(0)|答案(6)|浏览(128)

在各种情况下,我需要根据对象中的属性对Doctrine\Common\Collections\ArrayCollection进行排序,但没有找到可以立即执行此操作的方法,我这样做:

// $collection instanceof Doctrine\Common\Collections\ArrayCollection
$array = $collection->getValues();
usort($array, function($a, $b){
    return ($a->getProperty() < $b->getProperty()) ? -1 : 1 ;
});

$collection->clear();
foreach ($array as $item) {
    $collection->add($item);
}

我想这不是最好的方法,当你必须复制一切到本地PHP数组和回来。我想知道是否有一个更好的方法来“usort”一个Doctrine\Common\Collections\ArrayCollection。我错过了任何文件?

xmakbtuz

xmakbtuz1#

要对现有“集合”进行排序,请查找返回ArrayIterator的**ArrayCollection::getIterator()**方法。例如:

$iterator = $collection->getIterator();
$iterator->uasort(function ($a, $b) {
    return ($a->getPropery() < $b->getProperty()) ? -1 : 1;
});
$collection = new ArrayCollection(iterator_to_array($iterator));

最简单的方法是让repository中的查询处理您的排序。
假设您有一个与类别实体具有多对多关系的超实体。
例如,创建一个存储库方法,如下所示:

// Vendor/YourBundle/Entity/SuperEntityRepository.php

public function findByCategoryAndOrderByName($category)
{
    return $this->createQueryBuilder('e')
        ->where('e.category = :category')
        ->setParameter('category', $category)
        ->orderBy('e.name', 'ASC')
        ->getQuery()
        ->getResult()
    ;
}

......使分类变得相当容易。

jei2mxaa

jei2mxaa2#

从Doctrine 2.3开始,您可以使用Criteria API
例如:

<?php

public function getSortedComments()
{
    $criteria = Criteria::create()
      ->orderBy(array("created_at" => Criteria::ASC));

    return $this->comments->matching($criteria);
}

注意:此解决方案需要对$createdAt属性的公共访问或一个公共getter方法getCreatedAt()

8fsztsew

8fsztsew3#

如果你有一个ArrayCollection字段,你可以订购注解。例如:
假设一个名为Society的实体有许多许可证。

/**
* @ORM\OneToMany(targetEntity="License", mappedBy="society")
* @ORM\OrderBy({"endDate" = "DESC"})
**/
private $licenses;

这将按照endDate(日期时间字段)以降序对ArrayCollection进行排序。
参见原则文档:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#orderby

vi4fp9gy

vi4fp9gy4#

原则条件不允许按相关对象的属性排序。
如果你想这样做(像我一样),你必须像前面的响应一样使用Iterator的uasort方法,如果你使用PHP 7,你可以像这样使用Spaceship操作符<=>

/** @var \ArrayIterator $iterator */
$iterator = $this->optionValues->getIterator();
$iterator->uasort(function (ProductOptionValue $a, ProductOptionValue $b) {
    return $a->getOption()->getPosition() <=> $b->getOption()->getPosition();
});

return new ArrayCollection(iterator_to_array($iterator));
3pmvbmvn

3pmvbmvn5#

在没有@注解的最新Symfony 5.3中,您只需要

...
#[OrderBy(['sortOrder' => 'ASC'])]
private Collection $collection;

#[Column(type: 'integer')]
private int $sortOrder = 0;
...

在您实体中

wecizke3

wecizke36#

获取所有值,对这些值进行排序,然后用排序后的值覆盖属性,这怎么样?

public function sortMyDateProperty(): void
{
    $values = $this->myAwesomeCollection->getValues();
    usort($values, static function (MyAwesomeInterface $a, MyAwesomeInterface $b): int {
        if ($a->getMyDateProperty()->getTimestamp() === $b->getMyDateProperty()->getTimestamp()) {
            return 0;
        }

        return $a->getMyDateProperty() > $b->getMyDateProperty() ? 1 : -1;
    });

    $this->myAwesomeCollection = new ArrayCollection($values);
}

相关问题