Получите самое низкое значение в Twig - PullRequest
1 голос
/ 18 октября 2019

У меня есть связь OneToMany между моим продуктом и ссылками. В ссылках у меня есть столбец с именем price. Я передаю список продуктов моей ветке и хочу получить наименьшее значение из 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 позволяет мне показывать только одну цену, но это не самое низкое значение. Что я могу использовать, чтобы заставить это работать?

1 Ответ

1 голос
/ 19 октября 2019

по сути, это типичная уменьшение операция.

несколько различных способов сделать это (однако, остерегайтесь проблемы с запросом 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());
    });
}

вы также можете сделать что-то подобное в ветке (будьте осторожны: только в ветке> = 1,41 или ветке> = 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;
    }
}

после этого вы можете получить доступ к этой виртуальной переменной в twig через 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']) в функции хранилища.

этот гибридный подход гарантирует, что вы всегда получите минимальную цену, даже если функция хранилища не была вызвана.


в качестве дополнительного примечания: вызовы Reduction всегда можно заменить нацикл:

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

, который выглядит меньшепугающе и семантически примерно одно и то же ... что-то подобное возможно в ветке, но это ужасно уродливо, но все же может быть достаточно хорошим

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...