I have a product with optional variants like this:
SANDALS
- Color: red, green, blue
- Size: small, medium, large
- Brand: brandX, brandY
every product variant is related to a set of selections. Example: if I select Color: red, Size: large, Brand: brandX, this will related to a product with an id of 820.
The way that the option tree should look like is this:
"optionTree": [
[
0,
0,
[
820,
0
]
],
[
0,
[
0,
821
],
[
823,
0
]
],
[
[
824,
825
],
0,
0
]
]
As can be seen, there are 3 product options to choose from, thus the depth of the tree is 3 deep. every level of the array relates to a product option. The first depth deals with Color, the second deals with Size, and the third with Brand (there could be a variable number of options not just 3). Thus, traversing the entire array to the bottom will result in a product id which matches all 3 choices. (the index of the choices relate to the indexes in the 'optionTree' array, also 0s are used to represent dead-ends)
Question: how do i order product selection variants in an array tree in such a way that they relate to their respective choices?
lets say i have an array of products which i would like to insert into an empty tree:
$products_to_add = [
[
"choices" => ['red', 'medium', 'brandX'],
"product_id" => 820
],
[
"choices" => ['red', 'small', 'brandY'],
"product_id" => 821
],
[
"choices" => ['green', 'small', 'brandX'],
"product_id" => 822
],
[
"choices" => ['blue', 'large', 'brandY'],
"product_id" => 823
],
]
How would i transform the array above into a coherent 'optionTree' like the one showed previously? (php or javascript is fine)
CodePudding user response:
You can use a loop in which you mutate the final tree as you go. Before starting it, you could prepare a helper structure which translates the name of a variant (like "red") to an index in the relevant (sub)array of the target structure. In PHP:
$props = [
array_flip(["red", "green", "blue"]),
array_flip(["small", "medium", "large"]),
array_flip(["brandX", "brandY"])
];
Then in the main loop, you can benefit from the =&
assignment for having a pointer walk through the result tree and adding null
references (I prefer this than a 0) when arriving for the first time at a certain branch.
$optionTree = null;
foreach($products_to_add as $product) {
$node =& $optionTree;
foreach ($product["choices"] as $depth => $name) {
if ($node == null) $node = array_fill(0, count($props[$depth]), null);
$node =& $node[$props[$depth][$name]];
}
$node = $product["product_id"];
}
unset($node); // Safety, since it is a reference
After running this code, $optionTree
will have the desired value.