在 Twig 中获取最低值

Get lowest value in Twig

我的产品和链接之间存在 OneToMany 关系。在链接中,我有一个名为 price 的列,我正在将产品列表传递给我的 twig,我想从 price 中获取最低值。我该怎么做?

这就是我现在发布产品的方式:

{% for product in products %}
Name: {{ product.name }}
Price: {% for prodLink in product.getProduktLinks|slice(0, 1) %}
          <span class="price">{{ prodLink.price }}</span>
       {% endfor %}

slice 允许我只显示一个价格,但它不是最低值。我可以用什么来让它工作?

本质上,这是一个典型的 reduce 操作。

几种不同的方法(但是,请注意 n+1 查询问题):

// in the product entity class
public function getMinPrice() {
    return array_reduce($this->getProductLinks(), function($lowest, $link) {
        return min($lowest ?? $link->getPrice(), $link->getPrice());
    });
}

你也可以在 twig 中做类似的事情(注意:仅在 twig >=1.41 或 twig >=2.10 中):

product.productLinks|reduce((lowest, link) => min(lowest ?? link.price, link.price))

但是,最好调整您的产品存储库以在虚拟 属性 上设置最低价格,这样您就不会单独加载所有产品的所有链接...

老实说,我不太确定这是否有效

// in ProductRepository
public function getWithMinPrices() {
    $qb = $this->createQueryBuilder('product');
    $qb
       ->addSelect('(SELECT MIN(pl.price) FROM product.productLinks pl) as minprice')
       // do other query stuff like limiting number of products, searching etc.

    $result = $qb->getQuery()->getResult();
    // in contrast to normal queries, you now have an array of arrays with
    // one object and the minprice
    return array_map(function($row) {
        $product = $row[0];
        $product->minPrice = $row['minprice'];
        return $product;
    }
}

之后,您可以通过 product.minPrice

访问 twig 中的虚拟变量

您还可以结合这些方法:

protected $minPrice = null;
// in the product entity class
public function getMinPrice() {
    if(!is_null($this->minPrice)) {
        $this->minPrice = array_reduce($this->getProductLinks(), function($lowest, $link) {
            return min($lowest ?? $link->getPrice(), $link->getPrice());
        });
    }
    return $this->minPrice;
}
public function setMinPrice($minPrice) {
    $this->minPrice = $minPrice;
}

然后您应该在存储库函数中调用 $product->setMinPrice($row['minprice'])

这种混合方法将确保您始终获得最低价格,即使未调用存储库功能也是如此。


附带说明:reduce 调用总是可以用循环替换:

$min = null;
foreach($this->getProductLinks() as $link) {
   $min = min($min ?? $link->getPrice(), $link->getPrice());
}

看起来没那么吓人,语义上也差不多……twig 中可能有类似的东西,但丑得可怕,但可能仍然足够好