1,什么是笛卡尔乘积?
笛卡尔乘积是指在数学中,两个集合_X_和_Y_的笛卡尔积(Cartesian product),又称直积,表示为_X_×_Y_,第一个对象是_X_的成员而第二个对象是_Y_的所有可能有序对的其中一个成员-----百度定义
2,什么时候用笛卡尔积?
假设有俩个输入框,框1输入1,2俩个数,框2输入a,b,c三个参数,接口入参格式要{[1,a],[1,b],[1,c],[2,a],[2,b],[2,c]}这样的组合时,就可以用笛卡尔积函数
3,笛卡尔积函数
(1)如2中参数格式可用
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;
}
}
}
}
调用方式:
var result = descartes({'aa':['a1','a2'],'bb':['b1','b2'],'cc':['c1','c2']});
console.log(result);//result就是笛卡尔积
此时result=[["a1","b1","c1"],["a1","b1","c2"],["a1", "b2", "c1"],["a1", "b2", "c2"],["a2", "b1", "c1"],["a2", "b1", "c2"],["a2", "b2", "c1"],["a2", "b2", "c2"]]
(2)简单实现笛卡尔积
function cartesianProductOf() {
return Array.prototype.reduce.call(arguments, function(a, b) {
var ret = [];
a.forEach(function(a) {
b.forEach(function(b) {
ret.push(a.concat([b]));
});
});
return ret;
}, [[]]);
}
调用方式:
let result =cartesianProductOf(['1','2','3'],['a','b'])
console.log(result)
此时result=[["a1","b1","c1"],["a1","b1","c2"],["a1", "b2", "c1"],["a1", "b2", "c2"],["a2", "b1", "c1"],["a2", "b1", "c2"],["a2", "b2", "c1"],["a2", "b2", "c2"]]
(3)上述俩种方法的传参格式虽然不同,但得到的结果都是标准数组形式,如果想要对象数组的传参格式,需要对(1)函数稍加修改
function descartes(list) {
//parent上一级索引;count指针计数
var point = {};
var result = [];
var pIndex = null;
var tempCount = 0;
let obj = {};
//根据参数列生成指针对象
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'];
obj[index] = list[index][tempCount] ----区别
}
//压入结果数组
result.push(obj);
obj={}; -----区别
//检查指针最大值问题
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;
}
}
}
}
调用方式:
var result = descartes({'aa':['a1','a2'],'bb':['b1','b2'],'cc':['c1','c2']});
console.log(result);//result就是笛卡尔积
此时result=[{aa: "a1", bb: "b1", cc: "c1"},{aa: "a1", bb: "b1", cc: "c2"},{aa: "a1", bb: "b2", cc: "c1"},{aa: "a1", bb: "b2", cc: "c2"},{aa: "a2", bb: "b1", cc: "c1"},{aa: "a2", bb: "b1", cc: "c2"},{aa: "a2", bb: "b2", cc: "c1"},{aa: "a2", bb: "b2", cc: "c2"}]
这三种函数的主要区别在于:result的格式,注意传参要求即可。