JavaScript实现商品规格笛卡尔积组合算法
作者:闭包旅人时间:2026-10-31 00:27:29浏览:390
本文介绍如何利用JavaScript实现商品发布时的规格组合功能。通过笛卡尔积算法,将不确定的属性及其对应的属性值进行全排列组合,自动生成所有可能的商品SKU。文中提供了完整的JS代码示例,解析了Spec对象结构及组合逻辑,适用于电商后台商品管理场景。
在深入正文之前,先补充一些基础知识。
JavaScript笛卡尔积算法
该算法用于根据给定的对象或数组生成笛卡尔积结果。
//笛卡儿积组合
function descartes(list)
{
//parent上一级索引;count指针计数
var point = {};
var result = [];
var pIndex = null;
var tempCount = 0;
var temp = [];
//根据参数列生成指针对象
for(var index in list)
{
if(typeof list[index] == 'object')
{
point[index] = {'parent':pIndex,'count':0}
pIndex = index;
}
}
//单维度数据结构直接返回
if(pIndex == null)
{
return list;
}
//动态生成笛卡尔积
while(true)
{
for(var index in list)
{
tempCount = point[index]['count'];
temp.push(list[index][tempCount]);
}
//压入结果数组
result.push(temp);
temp = [];
//检查指针最大值问题
while(true)
{
if(point[index]['count']+1 >= list[index].length)
{
point[index]['count'] = 0;
pIndex = point[index]['parent'];
if(pIndex == null)
{
return result;
}
//赋值parent进行再次检查
index = pIndex;
}
else
{
point[index]['count']++;
break;
}
}
}
}
关于JS笛卡尔积算法的介绍仅为下文做铺垫,此处不再赘述,直接进入正题。
商品发布需求分析
一、需求描述
电商网站的商品发布功能类似于京东的商品详情页,如图所示。这种可选功能的后台生成机制是怎样的?实际上,你在前端看到的一个iPhone 6在后台发布时,并非只发布一个商品,而是多个。因为每一个选择出来的iPhone 6价格可能不同。发布商品时,这些可选项是从一堆属性和属性值中挑选出来的。问题是,发布时挑选的属性个数是不固定的,属性值也是多变的,因此生成的商品数量是由属性和属性值的组合决定的。

JavaScript代码实现
二、直接上代码
<script>
/**
* 商品属性类型
* 一个属性个数是不确定的
*/
var Spec = function(specName,specItems){
this.specName = specName; //属性名称
this.specItems = specItems;//数值值,是个数组,数组个数不确定
}
var result = [];//组合成产品集
/**
* 发布一款商品选择的一个属性,这是一个规格数组,数组个数不确定
* 根据这个选择的属性组合成不同的产品
*/
var selectSpec = [{specName:'容量',specItems:['16G','64G','128G']},
{specName:'颜色',specItems:['土豪金','银色','黑色','pink']},
{specName:'网络',specItems:['联通','移动','电信']}];
function combine(index, current){
if (index < selectSpec.length - 1){
var specItem = selectSpec[index];
var keya = specItem.specName;
var items = specItem.specItems;
if(items.length==0){
run( index + 1, current);
}
for (var i = 0; i < items.length; i++){
if(!items[i])continue;
var newMap = {};
newMap = $.extend(newMap,current);
newMap[keya] = items[i];
run( index + 1, newMap);
}
}else if (index == selectSpec.length - 1){
var specItem = selectSpec[index];
var keya = specItem.specName;
var items = specItem.specItems;
if(items.length==0){
result.push(current);
}
for (var i = 0; i < items.length; i++){
if(!items[i])continue;
var newMap = {};
newMap = $.extend(newMap,current);
newMap[keya] = items[i];
result.push(newMap);
}
}
}
combine(0, {});
console.info(result);
/**组合成产品集
* [Object { 容量="16G", 颜色="土豪金", 网络="联通"},
* Object { 容量="16G", 颜色="土豪金", 网络="移动"},
* Object { 容量="16G", 颜色="土豪金", 网络="电信"},
* Object { 容量="16G", 颜色="银色", 网络="联通"},
* Object { 容量="16G", 颜色="银色", 网络="移动"},
* Object { 容量="16G", 颜色="银色", 网络="电信"},
* Object { 容量="16G", 颜色="黑色", 网络="联通"},
* Object { 容量="16G", 颜色="黑色", 网络="移动"},
* Object { 容量="16G", 颜色="黑色", 网络="电信"},
* Object { 容量="16G", 颜色="pink", 网络="联通"},
* Object { 容量="16G", 颜色="pink", 网络="移动"},
* Object { 容量="16G", 颜色="pink", 网络="电信"},
* Object { 容量="64G", 颜色="土豪金", 网络="联通"},
* Object { 容量="64G", 颜色="土豪金", 网络="移动"},
* Object { 容量="64G", 颜色="土豪金", 网络="电信"},
* Object { 容量="64G", 颜色="银色", 网络="联通"},
* Object { 容量="64G", 颜色="银色", 网络="移动"},
* Object { 容量="64G", 颜色="银色", 网络="电信"},
* Object { 容量="64G", 颜色="黑色", 网络="联通"},
* Object { 容量="64G", 颜色="黑色", 网络="移动"},
* Object { 容量="64G", 颜色="黑色", 网络="电信"},
* Object { 容量="64G", 颜色="pink", 网络="联通"},
* Object { 容量="64G", 颜色="pink", 网络="移动"},
* Object { 容量="64G", 颜色="pink", 网络="电信"},
* Object { 容量="128G", 颜色="土豪金", 网络="联通"},
* Object { 容量="128G", 颜色="土豪金", 网络="移动"},
* Object { 容量="128G", 颜色="土豪金", 网络="电信"},
* Object { 容量="128G", 颜色="银色", 网络="联通"},
* Object { 容量="128G", 颜色="银色", 网络="移动"},
* Object { 容量="128G", 颜色="银色", 网络="电信"},
* Object { 容量="128G", 颜色="黑色", 网络="联通"},
* Object { 容量="128G", 颜色="黑色", 网络="移动"},
* Object { 容量="128G", 颜色="黑色", 网络="电信"},
* Object { 容量="128G", 颜色="pink", 网络="联通"},
* Object { 容量="128G", 颜色="pink", 网络="移动"},
* Object { 容量="128G", 颜色="pink", 网络="电信"}]
*/
</script>
以上所述是小编给大家介绍的基于JS实现的笛卡尔乘积之商品发布的相关内容,希望对大家有所帮助,同时也非常感谢大家对本站网站的支持,相信我们会做的更好!
作者最新文章
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
