输出每个可能的产品选项

huangapple go评论72阅读模式
英文:

Outputting every possible product option

问题

我曾经可以轻松应对这样的问题,但自从7年前离开开发领域以来,我失去了开发思维...

我的情况是,我试图输出客户可以选择的每个可能的产品选项以及由每个选项SKU附加到产品SKU组成的结果SKU。

数据存储得不太好,因为这是一个相当过时的网站。

以下是数据在MySQL中的存储方式,以及我在PHP中试图实现的内容。我将其限制为一个具有多个选项的产品。

产品ID 产品SKU
1 a
选项ID 选项产品ID
1 1
2 1
3 1
4 1
选项值ID 选项值选项ID 选项值
1 1 b
2 1 c
3 1 d
4 2 e
5 2 f
6 3 g
7 3 h
8 4 i
9 4 j
10 4 k

迭代每个选项的每种可能组合,并输出结果的SKU;

可能的SKU
abegi
acegi
adegi
abfgi
acfgi
adfgi
abehi
acehi
adehi
abegj
acegj
adegj
abegk
acegk
adegk
[等等]

当我像这样写出来时,这似乎非常简单,这让我想知道是否我漏掉了什么...

我目前正在迭代每个产品,对于每个产品,再对每个选项,然后对于每个选项,再对每个值,但显然这并不适用于每种可能的情况。

DB Fiddle - https://www.db-fiddle.com/f/vHWiKsKi9WUvvDwAa6pqw6/0

谢谢!

英文:

I used to be able to get my head around things like this in my sleep, but since leaving the dev world 7+ years ago, I've lost the dev brain...

My scenario is that I'm trying to output every possible product option that a customer can select, and the resulting SKU - made up of each option SKU appended to the product SKU.

The data isn't stored very well, as it's a pretty archaic site.

Below is an example of how the data is stored in MySQL, and what I am trying to achieve in PHP. I've limited it to one product with many options.

products.id products.sku
1 a
options.id options.product_id
1 1
2 1
3 1
4 1
option_values.id option_values.option_id option_values.value
1 1 b
2 1 c
3 1 d
4 2 e
5 2 f
6 3 g
7 3 h
8 4 i
9 4 j
10 4 k

Iterating over every possible combination of option(s), and output the resulting SKUs;

Possible SKUs
abegi
acegi
adegi
abfgi
acfgi
adfgi
abehi
acehi
adehi
abegj
acegj
adegj
abegk
acegk
adegk
[etc]

It seems very simple when I write it out like this, which makes me wonder if I'm missing something...

I'm currently iterating over every product, and for each product every option, then for each option every value, but obviously this doesn't cater for every possible scenario.

DB Fiddle - https://www.db-fiddle.com/f/vHWiKsKi9WUvvDwAa6pqw6/0

Thank you!

答案1

得分: 1

以下是代码部分的中文翻译:

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(/* 你的数据库设置 */);
$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;
}

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

英文:

The function to create the cartesian product of all the options is inspired by the answers to this question.

<?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);

If you are only interested in the sku strings you can reduce the function to:

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;
}

I am sure someone can provide a more efficient answer but this does produce the output requested, based on your example data.

huangapple
  • 本文由 发表于 2023年3月9日 23:21:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75686642.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定