悟道前端

闻道有先后,术业有专攻

生于1990,毕业于非知名学校的非专业码农,希望成为前端翘楚,并一直努力着

sku算法思考

@(blog)[sku, arithmetic]

SKU=Stock Keeping Unit(库存量单位),一个商品的属性会有若干个纬度,比如iphone手机,颜色纬度有:黑、白;存储容量纬度有:8GB、16GB、32GB;运营商纬度有:电信、联通、移动。一串完整的属性:黑色-8GB-电信的iphone称为一个sku,数据库中商品信息是按sku来存储的,在商品详情页的前端的交互中,如何确定一个商品的哪些sku属性是可选的,及他们的价格是多么,将是一件复杂的事情

Alt text 参考网址:http://www.yixinshang.com/product/1258

问题分析

基本数据

后台返回的skumap信息:

  1. var skuMap = {
  2. "227633277860,236223212497": { //属性,逗号分隔
  3. "id": 3238, //ID
  4. "sellPrice": "298.00", //售价
  5. "skuImageList": [
  6. "http://img01.yixinshang.com/1258_main_18.jpg" //对应图片
  7. ],
  8. "stock": 10 //库存
  9. },
  10. "227633277860,236223212496": {
  11. "id": 3239,
  12. "sellPrice": "298.00",
  13. "skuImageList": [
  14. "http://img01.yixinshang.com/1258_main_12.jpg"
  15. ],
  16. "stock": 10
  17. }
  18. }

页面html代码:

Alt text

对应属性id:

  1. 红色: 236223212496
  2. 黑色: 236223212497
  3. 均码: 227633277860

思路分析

最直观的方法就是在用户选择属性后,查出到前已选择属性,然后遍历未选择属性,算出所有可能的组合,然后去skumap查对应的sku,求出价格和库存,比如: 当用户选择了“均码”,遍历其它纬度的属性,就可以枚举出“均码-黑色”及“均码-红色”的组合,然后跟据其属性id组合,在skumap对象中找相应的sku信息。

好像也很简单,没有必要上升到算法的层面上,但是,想想,如果商品的属性纬度更大些,比如三层或四层那么匹配组合时的循环和遍历会特别多,而且很次的交互都会有重复的计算。

算法推算

思路

上述说到,难点在于,用户的选择是无序随意的,会产生很多组合,在计算组合的库存和价格时会消耗很多时间并且计算会出现重复。那么我们何不在页面初始化后,交互前就先把所有可能的组合一次都计算好,存为一个对象(数据字典),这样,在用户交互时,只需遍历一次,然后把组合值去数据字典里找就可以了,大至思路是:

由完整的sku信息:

  1. var skuMap = {
  2. "227633277860,236223212497": { //属性,逗号分隔
  3. "id": 3238, //ID
  4. "sellPrice": "298.00", //售价
  5. "skuImageList": [
  6. "http://img01.yixinshang.com/1258_main_18.jpg" //对应图片
  7. ],
  8. "stock": 10 //库存
  9. },
  10. "227633277860,236223212496": {
  11. "id": 3239,
  12. "sellPrice": "298.00",
  13. "skuImageList": [
  14. "http://img01.yixinshang.com/1258_main_12.jpg"
  15. ],
  16. "stock": 10
  17. }
  18. }

枚举出所有可能的组合值:

  1. var skuDD = {
  2. "227633277860": {stock: 20,...},
  3. "236223212497": {stock: 20,...},
  4. "236223212496": {stock: 20,...},
  5. "227633277860,236223212497": {stock: 10,...},
  6. "227633277860,236223212496": {stock: 10,...}
  7. }

属性纬度越大,这种算法的效率越明显

实践

根据上面的推演,把复杂的问题抽象成如下模型:

数据原型:[a, b, c, d]分别对应不同纬度里的一个值,通过算法枚举出如下组合字典:

  1. a, b, c, d,
  2. ab, ac, ad, bc, bd, cd,
  3. abc, abd, acd, bcd,
  4. abcd

观察上面的值,整理如下:

  1. a -> ab -> abc -> abcd
  2. -> abd
  3. -> ac -> acd
  4. -> ad
  5. b -> bc -> bcd
  6. -> bd
  7. c -> cd
  8. d

算法实现如下:

  1. var arr = ['a', 'b', 'c', 'd'];
  2. var len = arr.length;
  3. var sku = [];
  4. function skuRe(item, index){
  5. item = item || '';
  6. index = index || 0;
  7. if (index==len) return;
  8. for (var i=index; i<len; i++){
  9. var newItem = item+arr[i];
  10. sku.push(newItem);
  11. skuRe(newItem, ++index);
  12. }
  13. }
  14. skuRe();
  15. alert(sku); // ["a", "ab", "abc", "abcd", "abd", "ac", "acd", "ad", "b", "bc", "bcd", "bd", "c", "cd", "d"]
点击查看评论

Study

Think

Project