繁体   English   中英

在 Symfony2 Doctrine findBy() 中保留数组的初始顺序

[英]Preserve the initial order of array in Symfony2 Doctrine findBy()

我有一个包含以下值的 ID 数组( $newsList ): 4,2,1,3

我正在尝试从实体的数据库中获取一些数据:

$news=$this->getDoctrine()->getRepository('Bundle:News')->findBy(array('id' => $newsList));

$newsList数组代表来自 News 实体的真实 ID。

但是当我这样做时:

foreach($news as $n){
    $n->getId();
}

ID 依次为: 1,2,3,4

如何从 foreach 开始保留顺序?

你不能。

这就是从 DB 返回的方式。 如果你不指定ORDER BY查询子句,数据库将返回行,因为他们在存储,这通常是一样的id ASC

您应该在 PHP 中自行对它们进行排序。

试试这个:

$news = $this->getDoctrine()->getRepository('Bundle:News')->createQueryBuilder('n')
        ->where("n.id IN(:Ids)")
        ->setParameter('Ids', $newsList ) // $newsList = array(1,2,3,4,...)
        ->getQuery()
        ->getResult();

当您进行全局查询时,您可以仅按给定的属性和给定的排序顺序对结果进行排序,因此正如前面的答案所指出的那样,您不能。

要使您的结果完全按照您给出的数组排序,您可以执行以下操作:

$newsList = [3, 1, 4, 2];
$newsRepo = $this->getDoctrine()->getRepository('Bundle:News');

foreach ($newsList as $id) {
    $new = $newsRepo->findOneBy['id' => $id];

    if ($new !== null) {
        $news[] = $new;
    }
}

像这样,您的结果的排序与$newsList完全一样,例如:

foreach ($news as $n) {
    print $n->getId();
}

// Output: 3 1 4 2

我不知道您是否真的可以从返回的查询结果中对它们进行排序,但是您可以执行以下任一选项:

执行 foreach 循环并对每个结果执行“findByOne”:

foreach($newsList as $id) {
    $news[]=$this->getDoctrine()->getRepository('Bundle:News')->findBy(array('id' => $id));
}

之后对查询结果进行排序:

$news=$this->getDoctrine()->getRepository('Bundle:News')->findBy(array('id' => $newsList));
foreach($newsList as $id) {
    $sorted_news[] = $news[$id];
}

IMO 最好的解决方案是使用field函数来获得正确的新闻顺序:

$ids = [4, 1, 2, 3];
$news  = $this->getDoctrine()->getRepository('Bundle:News')->createQueryBuilder('n')
    ->select('n, field(n.id, :ids) as HIDDEN field')
    ->where("n.id IN (:ids)")
    ->setParameter('ids', $ids )
    ->orderBy(field)
    ->getQuery()
    ->getResult();

注意:此解决方案需要可在此处找到的自定义field函数。

您可以使用usort和 spaceship 运算符:

$newsList = [4, 2, 1, 3];
$news = $this->getDoctrine()->getRepository(News::class)->findBy(['id' => $newsList]);

$order = array_flip($newsList);
usort($news, function($a, $b) use ($order) {
    return $order[$a->getId()] <=> $order[$b->getId()];
});

// $news is now ordered by id 4,2,1,3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM