You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将商品变体选择集转换为符合规则的有序optionTree数组结构

实现思路
  1. 先定义所有维度的可选值列表,顺序对应optionTree每一层的数组下标
  2. 生成每个维度的可选值到下标的映射表,方便快速把选择项的字符串转为数组下标
  3. 递归初始化全0的多维度数组作为初始optionTree,维度数量、每一层长度和定义的维度完全匹配
  4. 遍历所有待插入商品,沿着选择项对应的下标逐层遍历optionTree,最后把最深处的位置的值替换为对应商品ID
PHP 实现代码
<?php
// 定义所有维度的可选值,顺序对应optionTree的层级
$dimensions = [
    ['red', 'green', 'blue'], // 第一层:颜色
    ['small', 'medium', 'large'], // 第二层:尺码
    ['brandX', 'brandY'] // 第三层:品牌
];

// 待插入的商品数组
$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
    ],
];

// 递归初始化全0的optionTree
function initTree(array $dimensions, int $currentDim = 0): array
{
    $layerSize = count($dimensions[$currentDim]);
    $tree = array_fill(0, $layerSize, 0);
    // 非最后一层,继续初始化下一层
    if ($currentDim < count($dimensions) - 1) {
        foreach ($tree as $index => $value) {
            $tree[$index] = initTree($dimensions, $currentDim + 1);
        }
    }
    return $tree;
}

// 生成每个维度的值到下标的映射表
$dimMaps = [];
foreach ($dimensions as $dimIndex => $dimValues) {
    $dimMaps[$dimIndex] = array_flip($dimValues);
}

// 初始化树
$optionTree = initTree($dimensions);

// 插入所有商品
foreach ($products_to_add as $product) {
    $choices = $product['choices'];
    $productId = $product['product_id'];
    $currentLayer = &$optionTree;
    foreach ($choices as $dimIndex => $choiceVal) {
        $pos = $dimMaps[$dimIndex][$choiceVal];
        // 到达最后一层,赋值商品ID
        if ($dimIndex === count($choices) - 1) {
            $currentLayer[$pos] = $productId;
            break;
        }
        // 移动到下一层
        $currentLayer = &$currentLayer[$pos];
    }
    unset($currentLayer); // 解除引用避免污染
}

// 输出结果
var_dump(json_encode($optionTree));
?>
JavaScript 实现代码
// 定义所有维度的可选值,顺序对应optionTree的层级
const dimensions = [
    ['red', 'green', 'blue'], // 第一层:颜色
    ['small', 'medium', 'large'], // 第二层:尺码
    ['brandX', 'brandY'] // 第三层:品牌
];

// 待插入的商品数组
const productsToAdd = [
    { 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 }
];

// 递归初始化全0的optionTree
function initTree(dimensions, currentDim = 0) {
    const layerSize = dimensions[currentDim].length;
    const tree = new Array(layerSize).fill(0);
    // 非最后一层,继续初始化下一层
    if (currentDim < dimensions.length - 1) {
        for (let i = 0; i < layerSize; i++) {
            tree[i] = initTree(dimensions, currentDim + 1);
        }
    }
    return tree;
}

// 生成每个维度的值到下标的映射表
const dimMaps = dimensions.map(dimValues => {
    return dimValues.reduce((map, val, index) => {
        map[val] = index;
        return map;
    }, {});
});

// 初始化树
const optionTree = initTree(dimensions);

// 插入所有商品
productsToAdd.forEach(product => {
    const { choices, product_id: productId } = product;
    let currentLayer = optionTree;
    choices.forEach((choiceVal, dimIndex) => {
        const pos = dimMaps[dimIndex][choiceVal];
        // 到达最后一层,赋值商品ID
        if (dimIndex === choices.length - 1) {
            currentLayer[pos] = productId;
            return;
        }
        // 移动到下一层
        currentLayer = currentLayer[pos];
    });
});

// 输出结果
console.log(JSON.stringify(optionTree));
输出结果示例

运行代码后得到的optionTree结构如下:

[
    [[0,821],[820,0],[0,0]],
    [[822,0],[0,0],[0,0]],
    [[0,0],[0,0],[0,823]]
]

完全符合规则要求,且支持任意数量的维度扩展,只需要修改dimensions数组的内容即可,不需要调整核心逻辑。

内容的提问来源于stack exchange,提问作者DiscreteTomatoes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:36:08