php "usort" 一个 Doctrine\Common\Collections\ArrayCollection?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16705425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:33:58  来源:igfitidea点击:

"usort" a Doctrine\Common\Collections\ArrayCollection?

phpdoctrine-orm

提问by luiges90

In various cases I need to sort a Doctrine\Common\Collections\ArrayCollectionaccording to a property in the object. Without finding a method doing that right away, I do this:

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

// $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);
}

I presume this is not the best way when you have to copy everything to native PHP array and back. I wonder if there is a better way to "usort" a Doctrine\Common\Collections\ArrayCollection. Do I miss any doc?

当您必须将所有内容复制到本机 PHP 数组并返回时,我认为这不是最好的方法。我想知道是否有更好的方法来“调整”一个Doctrine\Common\Collections\ArrayCollection. 我想念任何医生吗?

回答by Nicolai Fr?hlich

To sort an existing Collection you are looking for the ArrayCollection::getIterator()method which returns an ArrayIterator. example:

要对现有集合进行排序,您正在寻找返回 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));

The easiest way would be letting the query in the repositoryhandle your sorting.

最简单的方法是让存储库中的查询处理您的排序。

Imagine you have a SuperEntity with a ManyToMany relationship with Category entities.

想象一下,您有一个 SuperEntity 与 Category 实体之间的多对多关系。

Then for instance creating a repository method like this:

然后例如创建这样的存储库方法:

// 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()
    ;
}

... makes sorting pretty easy.

...使排序变得非常容易。

Hope that helps.

希望有帮助。

回答by ioleo

Since Doctrine 2.3 you can use the Criteria API

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

Eg:

例如:

<?php

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

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

Note: this solution requires public access to $createdAtproperty or a public getter method getCreatedAt().

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

回答by akrz

If you have an ArrayCollection field you could order with annotations. eg:

如果您有一个 ArrayCollection 字段,您可以使用注释进行排序。例如:

Say an Entity named Society has many Licenses. You could use

假设一个名为 Society 的实体拥有许多许可证。你可以用

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

That will order the ArrayCollection by endDate (datetime field) in desc order.

这将按结束日期(日期时间字段)按降序对 ArrayCollection 进行排序。

See Doctrine documentation: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#orderby

请参阅 Doctrine 文档:http: //docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#orderby

回答by Fabien Salles

Doctrine criteria does not allow to order by a property on a related object.

Doctrine 标准不允许按相关对象上的属性进行排序。

If you want to do it (like me), you have to use the uasortmethod of the Iterator like a previous response and if you use PHP 7, you can use the Spaceship operator <=>like this :

如果你想这样做(像我一样),你必须uasort像之前的响应一样使用Iterator的方法,如果你使用 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));