在 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 中可能有类似的东西,但丑得可怕,但可能仍然足够好
我的产品和链接之间存在 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
您还可以结合这些方法:
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 中可能有类似的东西,但丑得可怕,但可能仍然足够好