前端电商 sku 的全排列算法

什么是sku

针对电商而言:

1、SKU是指一款商品,每款都有出现一个SKU,便于电商品牌识别商品。

2、一款商品多色,则是有多个SKU,例:一件衣服,有红色、白色、蓝色,则SKU编码也不相同,如相同则会出现混淆,发错货。

SKU,定义为保存库存控制的最小可用单位,例如纺织品中一个SKU通常表示:规格、颜色、款式。 STOCK KEEP UNIT,这是客户拿到商品放到仓库后给商品编号,归类的一种方法。

聊聊常见的需求

我们有三个数组分别为

let names = ["星途 XT", "星途 XTL"]

let colors = ["黑色", "白色", "金色"]

let displacement = ["1.5L", "1.5T", "1.8L", "1.8T"]

最终输出结果为

[
	["星途 XT","黑色","1.5L"],
	["星途 XT","黑色","1.5T"],
	["星途 XT","黑色","1.8L"],
	["星途 XT","黑色","1.8T"],
	["星途 XT","白色","1.5L"],
	["星途 XT","白色","1.5T"],
	["星途 XT","白色","1.8L"],
	["星途 XT","白色","1.8T"],
	["星途 XT","金色","1.5L"],
	["星途 XT","金色","1.5T"],
	["星途 XT","金色","1.8L"],
	["星途 XT","金色","1.8T"],
	["星途 XTL","黑色","1.5L"],
	["星途 XTL","黑色","1.5T"],
	["星途 XTL","黑色","1.8L"],
	["星途 XTL","黑色","1.8T"],
	["星途 XTL","白色","1.5L"],
	["星途 XTL","白色","1.5T"],
	["星途 XTL","白色","1.8L"],
	["星途 XTL","白色","1.8T"],
	["星途 XTL","金色","1.5L"],
	["星途 XTL","金色","1.5T"],
	["星途 XTL","金色","1.8L"],
	["星途 XTL","金色","1.8T"]
]

由于这些属性数组是不定项的,所以不能使用简单的三重暴力循环来解决这个需求了

解决思路

我们采取递归回溯法来解决这个问题,那么最重要的问题就是设计我们的递归函数

思路分解

以上文所举的例子来说,比如我们目前的属性数组就是:names、colors、displacement,首先我们会处理 names 数组,很显然对于每个属性数组,都需要去遍历它,然后一个一个选择后再去和 下一个数组的每一项进行组合。
我们设计的递归函数接受两个参数:

index 对应当前正在处理的下标,是 names 还是 colors 或是 displacement。
prev 上一次递归已经拼接成的结果,比如 ['星途 XT, ‘黑色’]。
进入递归函数:

  1. 处理属性数组下标为0: 假设在第一次 星途 XT, 那此时我们有一个未完成的结果状态,假设我们叫它prev, 此时prev = [“星途 XT”].

  2. 处理属性数组的下标1: 那么就处理到 colors 数组的了,并且我们拥有 prev,在遍历 colors 的时候继续递归的去把 prev 拼接成 prev.concat(color),也就是 [‘星途 XT’, ‘黑色’] 这样继续把这个 prev 交给下一次递归。

  3. 处理属性数组的下标2:那么就处理到 displacement 数组的了,并且我们拥有了 name + color 的 prev,在遍历 displacement 的时候继续递归的去把 prev 拼接成 prev.concat(displacement),也就是 [‘星途 XT’, ‘黑色’, ‘1.5L’],并且此时我们发现处理的属性数组下标已经到达了末尾,那么就放入全局的结果变量 res 中,作为一个结果。

上代码

	let names = ["星途 XT", "星途 XTL"]

	let colors = ["黑色", "白色", "金色"]

	let displacement = ["1.5L", "1.5T", "1.8L", "1.8T"]

   	let combine = function (...chunks) {
       console.log(chunks, 'chunks')
       let res = []

       let helper = function (chunkIndex, prev) {
           let chunk = chunks[chunkIndex]
           let isLast = chunkIndex === chunks.length - 1
   		// 循环每个属性数组
           for (let val of chunk) {
               let cur = prev.concat(val)
               if (isLast) {
                   // 如果已经处理到数组的最后一项了 则把拼接的结果放入返回值中
                   res.push(cur)
               } else {
                   helper(chunkIndex + 1, cur)
               }
           }
       }

       // 从属性数组下标为 0 开始处理
       // 并且此时的 prev 是个空数组
       helper(0, [])

       return res
   	}

    console.log(combine(names, colors, displacement))

在这里插入图片描述
第一次进入递归流程。剩余流程可脑补

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值