JavaScript实现分组规格数组笛卡尔积生成商品SKU组合
商品规格交叉配对生成SKU数组实现方案
实现逻辑说明
- 先修复原始数据字段大小写不一致的问题,避免分组、取值错误
- 按规格类别(OptionName)完成分组
- 通过遍历完成全量交叉配对
- 按照指定结构组装最终SKU数组
适配2类规格场景的完整代码
当前你只有颜色、尺寸两类规格,直接用双层遍历即可实现1对1、1对2、2对1、2对2的全配对要求:
// 1. 归一化原始数据,兼容大小写不一致的字段名 const normalizedVariants = variantCats.map(item => ({ Id: item.Id, OptionName: item.OptionName || item.optionName, VariantName: item.VariantName || item.variantName })) // 2. 按规格类别分组,替换原有冗余的分组逻辑 const groupedMap = {} normalizedVariants.forEach(item => { if (!groupedMap[item.OptionName]) groupedMap[item.OptionName] = [] groupedMap[item.OptionName].push(item) }) const variantGroups = Object.values(groupedMap) // 3. 全量交叉配对,生成SKU数组 const skuList = [] const [firstCategory, secondCategory] = variantGroups firstCategory.forEach(optionA => { secondCategory.forEach(optionB => { skuList.push({ id: null, combinationStr: `${optionA.Id}_${optionB.Id}`, name: `${optionA.VariantName} ,${optionB.VariantName}`, hex: '#000', stock: 0, price: 0, priceDiscountType: OPTION.DISCOUNT_TYPE.NONE, priceDiscount: 0, weight: 10, code: '', attributeCode: 'a', active: true, productId: state.product.id // 替换为你项目中state里product.id的实际取值路径 }) }) })
扩展方案(支持3类及以上规格配对)
如果后续需要新增材质、款式等更多规格类别,要做多类规格的全组合,可以用通用笛卡尔积算法实现,不需要重复写遍历逻辑:
// 通用笛卡尔积计算函数,支持任意多组数组全组合 function getCartesianProduct(arrays) { return arrays.reduce((prevResult, currGroup) => { const temp = [] prevResult.forEach(prevItem => { currGroup.forEach(currItem => { temp.push(Array.isArray(prevItem) ? [...prevItem, currItem] : [prevItem, currItem]) }) }) return temp }) } // 生成所有规格组合并组装SKU const allCombinations = getCartesianProduct(variantGroups) const skuList = allCombinations.map(combination => ({ id: null, combinationStr: combination.map(opt => opt.Id).join('_'), name: combination.map(opt => opt.VariantName).join(' ,'), hex: '#000', stock: 0, price: 0, priceDiscountType: OPTION.DISCOUNT_TYPE.NONE, priceDiscount: 0, weight: 10, code: '', attributeCode: 'a', active: true, productId: state.product.id }))
结果验证
传入你提供的示例数据,最终生成的SKU数组共4条,完全符合预期:
- 组合1:
combinationStr: "1111111_2222222",name: "White ,XL" - 组合2:
combinationStr: "1111111_4444444",name: "White ,L" - 组合3:
combinationStr: "3333333_2222222",name: "GREEN ,XL" - 组合4:
combinationStr: "3333333_4444444",name: "GREEN ,L"
注意:你原有的分组代码存在两个问题:一是没有兼容字段名大小写不一致的问题,部分条目的
optionName是小写开头,直接取值会导致分组遗漏;二是内部定义的array变量没有实际作用,属于冗余代码,建议替换为上述分组逻辑。
内容的提问来源于stack exchange,提问作者mzgalang
相关产品推荐
相关产品推荐

