弑君者
2022/11/16阅读:103主题:默认主题
万字长文全面解析sku算法
theme: smartblue
什么是SKU
sku就是我们在京东或者拼多多购物的时候,选择的商品的属性。

通过动态图很容易明白什么是sku是什么,就是选择一件商品的不同属性。 从图中我们可以看到可选的sku有男裤黑色L、男裤白色L、女裤白色S、女裤白色L.
SKU中的概念
类型 :
类型就是上图中可选择的每一行数据,比如上图中就包含三个类型
[
// 第一种类型
[男裤,女裤],
// 第二种类型
[黑色,白色],
// 第三种类型
[S,L],
]
规格:
规格就是上图中的每个可以选择的属性,比如上图中的类型的综合,也就是
[男裤,女裤,黑色,白色,S,L]
可选择的SKU:
因为不是每件商品的规格都可以选择,比如上图中男裤白色S,就是不可选的sku,可选的sku有4种,如下:

SKU 算法难点分析
SKU 算法难点是在哪里呢?
我们可以想一下,如何是我们实现,我们会如何实现该功能。
难就难在如何当我们选择某个规格以后,如何确定还有哪些规格是可以选择的,比如选择了规格S以后,男裤和黑色就需要置灰,不能选择了,因为目前男裤黑色S的SKU是没有的。
所以难点就是需要点击某个规格以后,所有的规格都需要重新计算一遍,以便确定当前的规格是否可点。
所以这个时候,问题就转换为当选择了某个规格后,如何在可选的SKU中找出哪些规格还可以选择。
SKU质数算法
-
SKU质数算法使用的数据例子
// type: 规格类型,每个规格是指type中的一个值,比如男裤,女裤,黑色,白色等
type: [
["男裤", "女裤"],
["黑色", "白色"],
["S", "L"],
],
// 可选的SKU
const canUseSku = [
{
// 当前SKU的可选数量
stock: 1,
// 当前SKU包含的规格
skuName: ["男裤", "黑色", "S"],
// 当前SKU包含的规格对应的质数
skuPrime: [2, 5, 11],
},
{
stock: 1,
skuName: ["男裤", "白色", "L"],
skuPrime: [2, 7, 13],
},
{
stock: 1,
skuName: ["女裤", "黑色", "L"],
skuPrime: [3, 5, 13],
},
];
-
为什么选择质数
因为质数只有1和自身,所以适合来判断当前选择的规格是否在可选的SKU里边,例如
type: [
["男裤", "女裤"],
["黑色", "白色"],
["S", "L"],
],
这里边有三种规格类型,6个规格,那么如果把每个规格从小到大转换为质数,那就是
[2,3,5,7,11,13]
此时可选的SKU有
["男裤", "黑色", "S"],["男裤", "白色", "L"],["女裤", "黑色", "L"]
那么此时可选的SKU对应的质数就可以得出
[2, 5, 11],[2, 7, 13],[3, 5, 13]
此时如果把可选的SKU对应的质数相乘,就会得到
[2 * 5 * 11, 2 * 7 * 13 , 3 * 5 * 13]
-
整体实现逻辑
那么整个问题,就已经被转换为质数问题了
原来的问题是当选择某个规格,需要根据可选的SKU,重新计算那些规格可以重新选择
现在已经转换为当选择了某个质数,需要根据可选的SKU对应的质数,重新计算还有哪些质数可以重新选择。
那么如何判断某个质数,是不是可以选择呢?
其实可以通过查看可选的SKU对应的质数数组,查看当前的质数能否被整除,当某个质数能够被整除,就说明该指数对应的规格是可以被选择的。
比如刚开始的时候,肯定是没有任何一个质数被选择,所以可以设置初始值为1,然后遍历所有的质数,就会发现
[2,3,5,7,11,13] 这些质数都可以被选择,也就是这些质数对应的规格都可以被选择,也就是男裤、女裤、黑色、白色、S、L都可以被选择。
因为什么呢?
因为[2,3,5,7,11,13] 这些质数,可以被可选择的SKU质数集合,也就是[2 * 5 * 11, 2 * 7 * 13 , 3 * 5 * 13]整除。
此时当初始化选择的时候,已经解决了。
假设当选择了黑裤,也就是质数2被选中的时候,此时已经被选择的规格数组就是[2], 此时就需要再次遍历所有的规格,确定当前的规格是否可以被选择。
此时需要处理两种情况。
第一种: 规格和当前选择的规格是同一种规格类型的时候,此时就需要替换掉原来已经选择的规格数组,同一种规格类型。 比如现在已经选择了男裤,但是如果看女裤是不是可以选择的时候,此时就需要把已经被选择的规格数组[2],变成3,此时再利用[3]去遍历可选择的SKU质数集合,也就是[2 * 5 * 11, 2 * 7 * 13 , 3 * 5 * 13],此时发现3是可以被选择的,因为3是可以被可选择的SKU质数集合[2 * 5 * 11, 2 * 7 * 13 , 3 * 5 * 13]整除的。
第二种:
规格选择的不和已经选择的规格质数数组存在同一种类型的,比如目前选择了黑裤[2], 此时规格质数5、7、11、13都是可以选择的。
因为2 * 5、2 * 7、2 * 11、2 * 13都是可以被可选择的SKU质数集合[2 * 5 * 11, 2 * 7 * 13 , 3 * 5 * 13]整除的。
所以通过上面两种情况,当选择了男裤以后,也就是质数2以后,3、5、7、11、13
同理当选择了[2, 5] 以后,可选择的规格变成了3、7,11了, 13不能选择的原因是2 * 5 * 13 不能被可选择的SKU质数集合[2 * 5 * 11, 2 * 7 * 13 , 3 * 5 * 13]整除的。
-
其它
其它就是一些原理都是类似的,比如已经选择的规格,当再次点击以后,从已经选择的规格之中去除,然后再重新根据当前已经选择的规格,决定哪些规格可以进行选择。
SKU还有使用无向图进行解决的,但是无向图无法解决边公用的问题。
参考与源码
作者介绍