谁说前端没算法 您所在的位置:网站首页 sku是 谁说前端没算法

谁说前端没算法

2024-03-12 19:47| 来源: 网络整理| 查看: 265

什么是SKU

sku就是我们在京东或者拼多多购物的时候,选择的商品的属性。

sku 说明

通过动态图很容易明白什么是sku是什么,就是选择一件商品的不同属性。 从图中我们可以看到可选的sku有男裤黑色L、男裤白色L、女裤白色S、女裤白色L.

SKU中的概念

类型 :

类型就是上图中可选择的每一行数据,比如上图中就包含三个类型

[ // 第一种类型 [男裤,女裤], // 第二种类型 [黑色,白色], // 第三种类型 [S,L], ]

规格:

规格就是上图中的每个可以选择的属性,比如上图中的类型的综合,也就是

[男裤,女裤,黑色,白色,S,L]

可选择的SKU:

因为不是每件商品的规格都可以选择,比如上图中男裤白色S,就是不可选的sku,可选的sku有4种,如下:

image.png

SKU 算法难点分析

SKU 算法难点是在哪里呢?

我们可以想一下,如果是我们实现,我们会如何实现该功能呢?

难就难在当我们选择某个规格以后,如何确定还有哪些规格是可以选择的,比如选择了规格S以后,男裤和黑色就需要置灰,不能选择了,因为目前男裤黑色S的SKU是没有的。

所以难点就是当点击某个规格以后,所有的规格都需要重新计算一遍,以便确定规格是否可点或者disabled掉。

通过上面的分析,问题就转换为当选择了某个规格后,如何通过可选的SKU查找出哪些规格还可以点击或者哪些规格需要被disabled 掉。

SKU质数算法 SKU质数算法使用的数据例子 // type: 规格类型,每个规格是指type中的一个值,比如男裤,女裤,黑色,白色等 type: [ ["男裤", "女裤"], ["黑色", "白色"], ["S", "L"], ], // 可选的SKU const canUseSku = [ { // 当前SKU的可选数量 stock: 1, // 当前SKU包含的规格 skuName: ["男裤", "黑色", "L"], // 当前SKU包含的规格对应的质数 skuPrime: [2, 5, 13], }, { stock: 1, skuName: ["男裤", "白色", "L"], skuPrime: [2, 7, 13], }, { stock: 1, skuName: ["女裤", "白色", "S"], skuPrime: [3, 7, 11], }, { stock: 1, skuName: ["女裤", "白色", "L"], skuPrime: [3, 7, 13], }, ]; 为什么选择质数

因为质数只有1和自身,比如有一个数组里边都包含质数,比如有一个数组[2,5,7],那么此时如果我们通过把数组里边元素相乘, 得到2 * 5 * 7。

此时我们就很容易判断数组[2], [2,5,7],[2,5], 里边的元素是不是都在数组[2,5,7]中,

因为2 * 5 * 7 / 2 可以整除

2 * 5 * 7 / (2 * 5 * 7) 可以整除

2 * 5 * 7 / (2 * 5)可以整除

同时也很容易判断数组[2,3]里边不是所有的元素不是都在数组[2,5,7]中,

因为 2 * 5 * 7 / (2 * 3)不可以整除。

所以可以把规格和可选SKU都转成质数,通过这种方式来判断规格是否在可选的SKU里边,例如

type: [ // 一种规格类型,男裤是一种规格 ["男裤", "女裤"], // 一种规格类型 ["黑色", "白色"], ["S", "L"], ],

这里边有三种规格类型,6种规格,那么如果把每个规格,按照质数从小到大转换,那就是

// ["男裤", "女裤", "黑色", "白色","S", "L"], [2,3,5,7,11,13]

此时可选的SKU有

["男裤", "黑色", "L"],["男裤", "白色", "L"],["女裤", "白色", "S"],,["女裤", "白色", "L"],

那么此时可选的SKU对应的质数就可以得出

[2, 5, 13],[2, 7, 13],[3, 7, 11],[3, 7, 13]

此时如果把可选的SKU对应的质数相乘,就会得到

[2 * 5 * 13, 2 * 7 * 13 , 3 * 7 * 11,3 * 7 * 13]

当所有规格都转成质数,所有的可选SKU都转成质数以后,就可以通过质数的方法来根据当前已经选择的规格,查看其它规格是否可选或者需要disabled掉了。

SKU算法实现

整个问题,就已经被转换为质数问题了。

原来的问题是当选择某个规格,需要根据可选的SKU,重新计算那些规格可以选择?

现在已经转换为当选择了某个质数,需要根据可选的SKU对应的质数数组,重新计算还有哪些质数可以重新选择。

那么此时就有问题了,那么如何判断某个质数,是不是可以选择呢?

——————————可以先思考一下😁——————————————————

其实可以通过查看可选的SKU对应的质数数组,查看当前的质数能否被整除,当某个质数能够被整除,就说明该质数对应的规格是可以被选择的。

比如刚开始的时候,肯定是没有任何一个质数已经被选择了,所以可以设置初始值为1,然后遍历所有的质数,就会发现

[2,3,5,7,11,13] 这些质数都可以被选择,也就是这些质数对应的规格都可以被选择,也就是男裤、女裤、黑色、白色、S、L都可以被选择。

为什么呢?

因为[2,3,5,7,11,13] 这些质数,可以被可选择的SKU质数集合,也就是[2 * 5 * 13, 2 * 7 * 13 , 3 * 7 * 11,3 * 7 * 13]整除。

所以此时初始化的时候,哪些规格可以选择的问题,就已经解决了。

下面来处理当我们选择了某个规格的情况:

假设当选择了黑裤,也就是质数2被选中的时候,此时已经被选择的规格数组就是[2], 此时就需要再次遍历所有的规格,确定当前的规格是否可以被选择。

此时需要处理两种情况。

第一种: 规格和当前选择的规格是同一种规格类型的时候,此时就需要在已经选择的规格数组中替换掉原来已经选择的规格。 比如现在已经选择了男裤,但是如果看女裤是不是可以选择的时候,此时就需要把已经被选择的规格数组[2],变成 [3] (女裤对应的规格质数是3),此时再利用[3]去遍历可选择的SKU质数集合,也就是[2 * 5 * 13, 2 * 7 * 13 , 3 * 7 * 11,3 * 7 * 13],此时发现3是可以被选择的,因为3是可以被可选择的SKU质数集合[2 * 5 * 13, 2 * 7 * 13 , 3 * 7 * 11,3 * 7 * 13]中某一项整除的。

第二种:

规格不和已经选择的规格质数数组存在同一种类型的,比如目前选择了黑裤[2], 那么此时直接把规格添加到已经选择的规格质数数组,然后再查看当前规格是否可选就可以了。

比如规格质数5、7,13 可以发现5、7、13都是可以选择的。

为什么呢?

因为2 * 5、2 * 7、2 * 13都是可以被可选择的SKU质数数组[2 * 5 * 13, 2 * 7 * 13 , 3 * 7 * 11,3 * 7 * 13]中某一项整除的。

所以通过上面两种情况,当选择了男裤,也就是质数2以后,3、5、7,13 都可以被选择。

同理当选择了[2, 5] 以后,可选择的规格变成了7, 13了

3不能选择的原因是3 * 5 不能被可选择的SKU质数数组[2 * 5 * 11, 2 * 7 * 13 , 3 * 7 * 11, 3 * 7 * 13]中任何一项整除的。

同理11一样的道理。

优化

其实应该还可以进行优化,还是按照前面的思路, 假设目前规格有[2,3,5,7,11,13],一共这6种规格,此时此时可选的SKU数组变成有[2 * 7 * 11, 2 * 7 * 13 , 3 * 5 * 13]

那么此时其实可以提前先把所有的规格选择都计算出来,使用一个map缓存结果。

比如其中一条可选的SKU, 男裤白色S, 此时对应的质数为 2 、7、11, 可以这么看,此时的SKU为 [2, 7, 11], 假设库存量是1

那么此时可以认为 (* 代表任何规格) [2, *, *] 的库存量为1

[*, 7, *] 的库存量为1

[*, *, 11] 的库存量为1

[2, 7, *] 的库存量为1

[2, *, 11] 的库存量为1

[*, 7, 11] 的库存量为1

[2, 7, 11] 的库存量为1

那么此时可以把* 认为是1

此时可以转换为对象如下

{ // 2 * 1 * 1: 1, 2: 1, 7: 1, 11: 1, 14: 1, 22: 1, 77: 1, 154:1 }

同理另外一条SKU [2, 7, 13], 也可以转换为

{ // 2 * 1 * 1: 1, 2: 1, 7: 1, 13: 1, 14: 1, 26: 1, 91: 1, 182:1 }

同理另外一条SKU [3, 5, 13], 也可以转换为

{ // 3 * 1 * 1: 1, 3: 1, 5: 1, 13: 1, 15: 1, 3 * 13: 1, 5 * 13: 1, 3 * 5 * 13:1 }

如果把所有的SKU转换的对象合并那么就是

{ // 2 * 1 * 1: 1, 2: 2, 3: 1, 5: 1, 7: 2, 11: 1, 13: 2, // 3 * 5 : 1 15: 1, // 2 * 7: 1 14: 2, // 2 * 11: 1 22: 1, // 2 * 13: 1 26: 1, // 3 * 13: 1, 39: 1, // 5 * 13: 1, 65: 1, // 7 * 11 :1 77: 1, // 7 * 13 : 1 91: 1, // 2 * 7 * 11 :1 154:1, // 2 * 7 * 13 : 1 182:1, // 3 * 5 * 13:1 195:1 }

所以此时有了这个可选的对象,一切都变得很容易了。

这个可选的对象命名为itemMap

初始化的时候,遍历所有的规格,比如2、3、5、7、11、13,如果发现在itemMap中存在,那么就是可选的。 比如 2、3、5、7、11、13 都在itemMap中,所以这些对应的规格都是可选的。

当选择了其中一个规格,再选下一个的时候,也是查看是否在itemMap中, 比如当选择了男裤,也就是质数2的时候,此时如果想查看女裤是否可选,因为女裤和男裤是同一规格类型,所以此时应该是查看女裤对应的质数3是否是在itemMap中,如果在则是可选的,可以发现3是可选的。

当查看黑色是否可选的时候,因为黑色对应的质数是5,所以此时需要查看男裤黑色,也就是27 是不是在itemMap中,此时发现2 * 7 在itemMap中,所以此时黑色是可选的。其它规格同理可计算出。

当选择了男裤*黑色后,此时已经选择的质数就是2 * 5了,此时也需要查看,还有哪些规格可选,

比如此时查看女裤,因为女裤对应的质数是3,同时女裤和男裤是同一种规格类型,此时就要查看 3 * 5 是不是在itemMap中,可以发现3 * 5 在itemMap中,所以女裤可选。 同理白色对应的质数是7,那么此时就要查看2 * 7是不是在itemMap中,发现2 * 7 在 itemMap 中,所以白色也是可选的。

但是S对应的质数是11,因为 2 * 5 * 11 不在itemMap中,所以此时S不可选

L对应的质数是13,因为 2 * 5 * 13 也不在itemMap中,所以此时L也不可选。

整体思路

就是根据已经选择的规格,重新去查看其它的规格,根据可选的SKU,来决定当前规格是否可选。

其它实现方式

有的解法是使用无向图来解决,但是但是无向图无法解决边公用的问题,就是比如有a1,a2,b1,b2,c1,c2 六种规格,当可选的SKU是 [a1 * b1 *c1, a1 * b2 * c2, a2 * b1 * c2] 的时候,也会把 a1 * b1 * c2 认为是合法的SKU.

参考与源码

电商最小存货 - SKU 和 算法实现

GITHUB 源码



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有