实现商品规格排列组合

40 阅读2分钟

模拟数据如下

let arr = [{
	key: "a",
	value: [1, 2, 3]
}, {
	key: "b",
	value: [4, 5, 6]
}, {
	key: "c",
	value: [7, 8, 9]
}]

代码思路:通过下标的排列实现 开始的时候设想是从[0,0,0]开始,从前往后递增:

[0,0,0]
[1,0,0]
[2,0,0]
[1,1,0]
[1,2,0]
[1,1,1]
[1,1,2]
[1,2,1]
[1,2,2]
[2,2,2]

很明显是不行的,这种排列只能有10个组合,后来经过几次调整都失败后,把所有组合手写出来发现是递增的方向错了,类似于进制,需要从后往前递增才对 修改后代码如下:

let label = [], maxIndexArr = [], indexArr = [], table = []
arr.forEach(item => {
	label.push(item.key)
	maxIndexArr.push(item.value.length - 1)
	indexArr.push(0)
})
// maxIndexArr最大下標組,indexArr當前下標組,currentIndex是當前的修改的下標,
// 算法思路:从后往前开始递增,当前下标达到最大则清零,再循环判断前面下标是否达到最大,不是的话前面下标加一,是的话就结束运行

let continueToDo = true, currentIndex = indexArr.length-1, count = 0
while (continueToDo) {
count++
	let obj = {};
	console.log(indexArr, currentIndex)
	arr.forEach((item, index) => {
		obj[item.key] = item.value[indexArr[index]]
	})
	table.push(obj)
	
	if (++indexArr[currentIndex] > maxIndexArr[currentIndex]) {
	// 	下标达最大,开始执行判断是否能进位
		let index = currentIndex-1
		let find = true
		while (find){
			if(indexArr[index] === maxIndexArr[index]){
				if(index===0){
					continueToDo = false
					find = false
				} else{
					index--
				}
			}else{
				indexArr[index]++
				indexArr.fill(0,index+1)
				find = false
			}
		}
	}
}
console.log(table)

打印输出为:

[ 0, 0, 0 ] 2
[ 0, 0, 1 ] 2
[ 0, 0, 2 ] 2
[ 0, 1, 0 ] 2
[ 0, 1, 1 ] 2
[ 0, 1, 2 ] 2
[ 0, 2, 0 ] 2
[ 0, 2, 1 ] 2
[ 0, 2, 2 ] 2
[ 1, 0, 0 ] 2
[ 1, 0, 1 ] 2
[ 1, 0, 2 ] 2
[ 1, 1, 0 ] 2
[ 1, 1, 1 ] 2
[ 1, 1, 2 ] 2
[ 1, 2, 0 ] 2
[ 1, 2, 1 ] 2
[ 1, 2, 2 ] 2
[ 2, 0, 0 ] 2
[ 2, 0, 1 ] 2
[ 2, 0, 2 ] 2
[ 2, 1, 0 ] 2
[ 2, 1, 1 ] 2
[ 2, 1, 2 ] 2
[ 2, 2, 0 ] 2
[ 2, 2, 1 ] 2
[ 2, 2, 2 ] 2
[
  { a: 1, b: 4, c: 7 }, { a: 1, b: 4, c: 8 },
  { a: 1, b: 4, c: 9 }, { a: 1, b: 5, c: 7 },
  { a: 1, b: 5, c: 8 }, { a: 1, b: 5, c: 9 },
  { a: 1, b: 6, c: 7 }, { a: 1, b: 6, c: 8 },
  { a: 1, b: 6, c: 9 }, { a: 2, b: 4, c: 7 },
  { a: 2, b: 4, c: 8 }, { a: 2, b: 4, c: 9 },
  { a: 2, b: 5, c: 7 }, { a: 2, b: 5, c: 8 },
  { a: 2, b: 5, c: 9 }, { a: 2, b: 6, c: 7 },
  { a: 2, b: 6, c: 8 }, { a: 2, b: 6, c: 9 },
  { a: 3, b: 4, c: 7 }, { a: 3, b: 4, c: 8 },
  { a: 3, b: 4, c: 9 }, { a: 3, b: 5, c: 7 },
  { a: 3, b: 5, c: 8 }, { a: 3, b: 5, c: 9 },
  { a: 3, b: 6, c: 7 }, { a: 3, b: 6, c: 8 },
  { a: 3, b: 6, c: 9 }
] 27