个人的SKU选择逻辑实现思路,利用集合思想。

来源:3-8 完成SKU的逻辑选择

九天云歌

2020-04-09 18:04:20

考虑用未选标签和已选标签能否组成合法pair来判断未选标签是否被禁用。

 定义:若某个标签X和当前已选的一个标签Y配对后,在sku列表中出现过,则认为X和Y能组成合法pair,或他们在彼此的合法pair集合中。

 对于单选的情况,比如只选择了颜色青芒色,那么只需要判断别的行的cell和青芒色能否组成合法pair即可。对于同行其他颜色,能被显示出来的表示一定是存在的,颜色切换不受已选颜色影响。

对于多选的情况,比如同时选了青芒色和七龙珠,那么颜色中的其他颜色可能因为七龙珠的存在而被禁用。图案中的其他图案同理,可能受到青芒色的影响而被禁用。

 故得到规律,最终能选的标签,应该是当前已选标签合法pair的交集。因为交集代码实现有点烦,故利用集合交兵补的思想,转化为:所有禁用标签,应该是每个已选标签 非法pair集合的并集。

 为此整体思路:

1.      从sku列表中建立整体的合法pair集合。

2.      响应用户点击。

3.      更新禁用状态。

 第一步,建立合法pair集合。在老师的方案中,通过组合思想求出C13,C23,C33,但是此处的思路是只看pair适合合法,故只求C23即可。然后集合去重以下。得到结果如下:

 http://img.mukewang.com/climg/5e8ef24e09043f1d05540268.jpg

第二步,响应用户点击。根据cell原先的状态,分为三种响应模式:已选到待定(即反选),待定到已选,点击禁用标签。用一个switch语句可以分流处理。如下:

PS:此处我把坐标x,y在建立cell的时候就保存在cell里了,个人觉得这比组件中传参更清晰。

http://img.mukewang.com/climg/5e8ef25f09dac83d05540376.jpg

Judge方法中涉及到两个状态切换函数selectedToWaiting和waitingToSelected,顾名思义,仅做最简单的状态切换。对于waitingToSelected,包括两种情况,该行原来未选和原来已选,后一种情况可以分解成先反选再重新选这两步。在更新cell状态后还需记录当前用户已选的标签。

为了记录当前已选的标签,需要一个数据结构保存状态,类似老师方案中的SkuPending类,我是直接在FenceGroup类中定义一个对象属性,fenceSelected,它是一个数组,按序记录每一行(每个fence)中所选的标签,未选则为null。

http://img.mukewang.com/climg/5e8ef270094ad4d205540566.jpg

 对于点击事件初步响应以后,再考虑更新禁用状态,思路是,对于任一个已选的标签Mij (0<=i<行数, 0<=j<列数),遍历所有cell,把和M不能配对的标签都标记为FORBIDDEN。因此是一个两重的遍历,外层遍历fenceSelected,内层遍历所有cell。把内层遍历单独封装成一个方法checkPair,检查和当前Mij的配对情况。这里有个小细节就是顺序问题,若待判断标签Nab的行号小于Mij (即a<i),则拼接的时候Nab放前面,否则在后面。同行的情况无需考虑(a=i),需由其他已选标签来判断它的状态。拼接完成后检查是否在合法pair的总集当中,不在就标记为pair。所有循环结束后即可得到每个已选标签Mij非法pair的并集。

http://img.mukewang.com/climg/5e8ef28709e8b11800000000.jpg

 由于在update过程中,仅存在WAITING到FORBIDDEN这一单向变化,故在用户的多次点击过程中,原先标记的FORBIDDEN可能会遗留在当前的状态中,为了消除这一bug,需要在update前先置位,即把所有未选标签都重置为WAITING,去除点击历史的影响。故在judge中,调用update前先调用flush方法,遍历所有cell重置状态,已选的标记为已选,完成update前的准备工作。

http://img.mukewang.com/climg/5e8ef2e609f99ef705540316.jpg 

后记:在老师的提示下合理组织数据结构和类关系之后,感觉用这样的思路去更新状态时,思维负担不大。一开始光想着用合法pair的交集去做,后来发现实现有点麻烦,转换下思路,用禁用pair的并集去做发现思路就很清晰了。关于算法复杂度,对于N行M列的规格表,主要时间复杂度集中在检查每个已选标签的配对情况,为O(N2M)。但是考虑到实际情况中N和M并不会太大,暴力遍历也只在客户端进行。适当牺牲下性能换来思路的简便是可以接受的。然后如果用户频繁切换标签(选择困难症?),则会导致中间生成较多记录状态的小对象,本人对js垃圾回收不是很了解,但是感觉这种情况应该不太会出现。


写回答

2回答

7七月

2020-04-10

原谅我没有那么多时间去看这么复杂的思路 ?。。。

不过你可以仔细对比下你的方案和我的方案的优缺点

0

7七月

2020-04-10

但是 同学确实很棒。。。能举一反三,这样编程学习一定能够进步的很快

0

Java全栈工程师

从Java到全栈,开发带SKU的真实企业级电商项目(附赠整套UI框架,配套升级Vue3.0内容)

2091 学习 · 3073 问题

查看课程