问题描述本题来自选择商品属性的场景。例如,我们在购买衣服、鞋子等时,一般需要选择合适的颜色、尺码等属性。先了解一下sku的学术概念。最小存货管理单位(StockKeepingUnit,SKU)是一个会计术语,定义为存货管理中可用的最小单位。例如,纺织品中的一个SKU通常代表规格、颜色和款式,而单个产品在连锁零售店中有时被称为一个SKU。库存管理最小单位可以区分不同商品销售的最小单位,是商品采购、销售、物流、财务管理科学管理的需求,也是POS、MIS系统数据统计的需求,通常对应代码的管理信息系统。——维基百科最小存货单位简单结合上面的例子:sku就是你在购物网站上购买的最终产品,上图中选择的对应属性是:颜色黑色-尺码37。先看后端。数据结构一般是这样的,一个线性数组,每个元素是一个描述当前sku的map,例如:[{"color":"red","size":"large","model":"A","skuId":"3158054"},{"color":"white","size":"medium","model":"B","skuId":"3133859"},{"color":"blue","Size":"Small","Model":"C","skuId":"3516833"}]前端显示时,显然需要按不同的属性进行分组和分组。目的是让用户通过属性维度来进行选择,分组后的数据大概是这样的:{"color":["red","white","blue"],"size":["big""medium","small"],"Themodel":["A","B","C"]}对应网页上的这样一个UI。这时候,就会出现问题。这些元子属性的集合(用户的选择路径)远大于真正可以组合的集合,比如上面的属性集合可以组合成一个笛卡尔积,即。可以组合成如下顺序:[["red","big","A"],//?["red","big","B"],["red","big","C"],["红","中","A"],["红","中","B"],["红","中","C"],["红","小","A"],["红","小","B"],["红","小","C"],["白","大","A"],["白","大","B"],["白","大","C"],["白","中","A"],["白","Medium","B"],//?["White","Medium","C"],["White","Small","A"],["White","Small","B""],["白色","小","C"],["蓝色","大","A"],["蓝色","大","B"],["蓝色",“大”,“C”],["blue","medium","A"],["blue","medium","B"],["blue","medium","C"],["blue","small","A"],["Blue","Small","B"],["Blue","Small","C"]//?]根据公式可知,1由3元素,每个元素是由3个元素的子集组成的集合,可以组成的笛卡尔积共有3的3次方,即27种,但是源数据只能组成3种组合。这种情况最好提前判断路径不是可选的,然后变灰告诉用户,否则会造成误解判断规则见下图,如果我们定义红色为当前选中商品的属性,即当前选中的商品是red-big-A,此时如何确认其他未选中的属性是否可以组成可选路径?规则如下:假设当前用户要选择white-big-A,但是这个选择路径不存在,那么我们将白色设置为灰色等等。来确认是否blue属性可用,需要查找blue-big-A路径是否存在...解决方案是基于上面的逻辑代码实现思路:遍历所有未被选中的元素:"white","blue"","medium",""Small","B","C"遍历所有属性行:"Color","Size","Model"取:a)当前元素b)其他被选中的非当前元素当前元素,并形成一条路径,判断这条路径是否存在,如果不存在,则将当前元素a置灰。看起来问题好像已经解决了,然而……我们忽略了一个很重要的问题:虽然上面的例子中白色元素是灰色的,但是白色元素其实是可以点击的!因为用户可以选择white-middle-B路径。如果用户点击白色,情况就会变得复杂得多。我们假设用户只选择了一个元素白色。如何判断其他未选中的元素是否可选?即:如何确认“大”,"Medium","Small","A","B","C"需要变灰吗?注意这里不需要确认"red"和"blue"是否可选,因为里面的元素属性都是single-select,当前属性中的任意一个元素都是可选的,可以缩小问题范围。我们先缩小问题范围:在当前情况下(只选了一个白色)如何确定大小“big”需要变灰了?按照我们之间的逻辑你可能会想到,需要分别搜索:White-Big-AWhite-Big-BWhite-Big-C如果都不存在,就将sizeBig设置为灰色。问题貌似解决了,其实这是不对的,因为没有选择型号。所以只需要知道white-big是不是optional即可。同时还有一个问题,如果选择了number是不确定的,维数可以增加到不确定吗?这种情况下,如果还是按照之前的算法,即使实现了,也很难复杂化。在t他的时代,我们需要考虑转变思维方式。在调整思路之前,我们总是逆向思考,找出那些不是可选的、应该变灰的元素。现在我们正向思考,如何判断属性是否可选。而多维情况下用户可以跳过选择。例如:用户选择了白色的两个元素,我们回看图B中的原始数据[{"color":"red","size":"big","model":"A","skuId":"3158054"},{"color":"white","size":"medium","model":"B","skuId":"3133859"},{"color":"blue","Size":"Small","Model":"C","skuId":"3516833"}]//即[["Red","Big","A"],//存在["White","Middle","B"],//存在["Blue","Small","C"]//存在]显然:如果第一条数据是"Red","Big","A"存在,那么下面的子组合一定存在:以下子组合必须存在:百种B百-中百-B中-B百-中-B...我们预先计算出所有存在路径中的子组合,该算法称为取集合的所有子集,数学称为幂设置,并形成所有现有路径的表格。算法如下:/***获取集合“幂集”的所有子集arr=[1,2,3]i=0,ps=[[]]:j=0;j
