js笛卡尔积数组整理实现

97 阅读1分钟

需求

数组笛卡尔积的实现,例如

let arr1 = [1, 2, 3]
let arr2 = ['a', 'b', 'c']
let arr3 = [8, 9]

//整理成
 [1, "a", 8]
 [1, "a", 9]
 [1, "b", 8]
 [1, "b", 9]
 [1, "c", 8]
 [1, "c", 9]
 [2, "a", 8]
 [2, "a", 9]
 [2, "b", 8]
 [2, "b", 9]
 [2, "c", 8]
 [2, "c", 9]
 [3, "a", 8]
 [3, "a", 9]
 [3, "b", 8]
 [3, "b", 9]
 [3, "c", 8]
 [3, "c", 9]

方式一

descartes(...args) {
		 if (args.length < 2) {
		 return args[0] || [];
		 } 
	 return [].reduce.call(args, (col, set) => {
			 let res = [];
				 col.forEach(c => {
					 set.forEach(s => {
					 let t = [].concat(Array.isArray(c) ? c : [c]);
					 t.push(s);
				 res.push(t);
			 });
		  });
	 	return res;
	 });
 },
this.descartes(arr1, arr2, arr3)

方式二

descartes2(list) {
		 // parent上一级索引;count指针计数
		 let point = {};
		 let result = [];
		 let pIndex = null;
		 let tempCount = 0;
		 let temp = []; 
			 // 根据参数列生成指针对象
			 for (let index in list) {
			 if (typeof list[index] === 'object') {
			 point[index] = {
				 parent: pIndex,
				 count: 0
			 };
				 pIndex = index;
			 }
				} 
			 // 单维度数据结构直接返回
		 if (pIndex == null) {
			 return list;
		 } 
				// 动态生成笛卡尔积
		 while (true) {
			 let index;
		 for (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;
		 }
	 }
 },
this.descartes2([arr1, arr2, arr3])

这是整理过后的数据格式,根据实际情况来整理成数组对象格式