suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Umformulierter Titel: Alle möglichen Produktoptionen auflisten

<p>以前,我可以轻松处理这样的事情,但自从7年前离开开发世界以来,我失去了开发思维...</p> <p>我的情况是,我正在尝试输出客户可以选择的每个可能的产品选项以及生成的SKU - 由每个选项的SKU附加到产品的SKU。</p> <p>数据存储得不好,因为这是一个相当古老的网站。</p> <p>下面是MySQL中存储数据的示例,以及我在PHP中尝试实现的目标。我将其限制为一个具有多个选项的产品。</p> <table class="s-table"> <thead> <tr> <th>products.id</th> <th>products.sku</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>a</td> </tr> </tbody> </table> <table class="s-table"> <thead> <tr> <th>options.id</th> <th>options.product_id</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>1</td> </tr> <tr> <td>3</td> <td>1</td> </tr> <tr> <td>4</td> <td>1</td> </tr> </tbody> </table> <table class="s-table"> <thead> <tr> <th>option_values.id</th> <th>option_values.option_id</th> <th>option_values.value</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>1</td> <td>b</td> </tr> <tr> <td>2</td> <td>1</td> <td>c</td> </tr> <tr> <td>3</td> <td>1</td> <td>d</td> </tr> <tr> <td>4</td> <td>2</td> <td>e</td> </tr> <tr> <td>5</td> <td>2</td> <td>f</td> </tr> <tr> <td>6</td> <td>3</td> <td>g</td> </tr> <tr> <td>7</td> <td>3</td> <td>h</td> </tr> <tr> <td>8</td> <td>4</td> <td>i</td> </tr> <tr> <td>9</td> <td>4</td> <td>j</td> </tr> <tr> <td>10</td> <td>4</td> <td>k</td> </tr> </tbody> </table> <p>迭代每个选项的每个可能组合,并输出生成的SKU;</p> <table class="s-table"> <thead> <tr> <th>可能的SKUs</th> </tr> </thead> <tbody> <tr> <td>abegi</td> </tr> <tr> <td>acegi</td> </tr> <tr> <td>adegi</td> </tr> <tr> <td>abfgi</td> </tr> <tr> <td>acfgi</td> </tr> <tr> <td>adfgi</td> </tr> <tr> <td>abehi</td> </tr> <tr> <td>acehi</td> </tr> <tr> <td>adehi</td> </tr> <tr> <td>abegj</td> </tr> <tr> <td>acegj</td> </tr> <tr> <td>adegj</td> </tr> <tr> <td>abegk</td> </tr> <tr> <td>acegk</td> </tr> <tr> <td>adegk</td> </tr> <tr> <td>[等等]</td> </tr> </tbody> </table> <p>当我像这样写出来时,它似乎非常简单,这让我想知道我是否遗漏了什么...</p> <p>我目前正在迭代每个产品,对于每个产品的每个选项,然后对于每个选项的每个值,但显然这不能满足每种可能的情况。</p> <p>DB Fiddle - https://www.db-fiddle.com/f/vHWiKsKi9WUvvDwAa6pqw6/0</p> <p>谢谢!</p>
P粉976737101P粉976737101467 Tage vor541

Antworte allen(1)Ich werde antworten

  • P粉046878197

    P粉0468781972023-08-21 00:52:52

    创建所有选项的笛卡尔积的函数受到这个问题的答案的启发。

    &lt;?php
    
    function all_skus(array $product) {
        $skus = [];
        $result = [[]];
    
        foreach ($product['options'] as $key => $option) {
            $append = [];
            foreach ($result as $options) {
                foreach ($option as $value) {
                    $append[] = $options + [$key => $value];
                }
            }
            $result = $append;
        }
    
        foreach ($result as $option_set) {
            $skus[] = $product['sku'] . implode($option_set);
        }
    
        return $skus;
    }
    
    
    $pdo = new PDO(/* your stuff here */);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
    
    $res = $pdo->query('
                SELECT `o`.`product_id`, `p`.`sku`, `ov`.`option_id`, `ov`.`value`
                FROM `products` `p`
                JOIN `options` `o` ON `p`.`id` = `o`.`product_id`
                JOIN `option_values` `ov` ON `o`.`id` = `ov`.`option_id`'
            );
    
    $nested = [];
    foreach ($res as $row) {
        $nested[$row->product_id]['options'][$row->option_id][] = $row->value;
        $nested[$row->product_id]['sku'] = $row->sku;
    }
    
    $skus = [];
    foreach ($nested as $i => $product) {
        $skus = array_merge($skus, all_skus($product));
        unset($nested[$i]);
    }
    
    var_dump($skus);
    

    如果你只对sku字符串感兴趣,你可以简化函数为:

    function all_skus(array $product) {
        $result = [$product['sku']];
    
        foreach ($product['options'] as $option) {
            $append = [];
            foreach ($result as $options) {
                foreach ($option as $value) {
                    $append[] = $options . $value;
                }
            }
            $result = $append;
        }
    
        return $result;
    }
    

    我相信有人可以提供一个更高效的答案,但这个答案根据你的示例数据产生了所需的输出。

    Antwort
    0
  • StornierenAntwort