两万字长文-电商sku组合查询状态细究与实现

本文详细探讨了电商商品详情页中,关于SKU选择查询问题的实现思路。通过分析商品属性组合,提出了计算单属性所属下标集合、构建对象以及算法优化的方法。针对库存为0的单SKU数据缓存、数组交集计算和避免模糊正则表达式的使用等方面进行了优化,以提高性能。最后,总结了实现过程中需要注意的事项。
摘要由CSDN通过智能技术生成

最近做到一个需求,需要做一个类似于京东或者淘宝等电商的商品详情页,其中有一个功能就是商品SKU的选择查询问题

如上图,网络类型、机身颜色、套餐类型、存储容量这些每一个都是一个 SKU属性,当选择好了所有的 SKU属性后,会组合成一个完整的 SKU,对应一个具体的商品,然后就可以给出这条 SKU对应的商品的库存和价格等信息

并且,当点选了某些 SKU属性后,会自动根据当前已经点选的 SKU属性,来计算出当前条件下库存为 0SKU组合,给予按钮置灰不可选的交互

一开始接到这个需求的时候,评审需求的后端和同组合作的前端小伙伴都认为这是一个难点,需要好好调研考量一下,而我则是邪魅一笑,觉得这东西不就是一个组合嘛,算法能写就写,不能写大不了来个暴力循环查找,小场面啦

然而,当我开始着手做的时候才发现跟平常确实不一样,这些代码好像不能闭着眼睛写

实现思路

当我发现这个功能确实有点小难度的时候,我就开始在网上搜相关文章了,这才发现相关文章好像都写的比较煞有其事,跟什么《你绝对不知道的数组的十种用法》什么《原型链全场最佳分析》什么《我的函数式编程不可能那么可爱》什么《三年前端大厂面试经历》都不太一样,看起来居然需要带着脑子,而且相关文章较少,除去那些抄来抄去的以及我没搜到的之外,几篇真正有实用价值的:

我看完之后,顿时陷入了沉思

既然塑料恐龙是塑料做的,而塑料来源于石油,石油又是远古恐龙尸体转化成的。
那么是不是说,塑料恐龙就是真的恐龙?

这些文章描述得感觉不是很清楚,主要是没有完整可运行代码,看的云里雾里的,照着他们说的来做,还不如我自己重新写个,不过还是有些借鉴意义的

  • 首先,给定几组 SKU的属性,那么根据这些属性组合出来的 sku肯定是可以被全部列举出来的,而且考虑到现实业务使用中,属性并不会太多,无需关心极端情况,所以哪怕全部穷举,对性能也没多大损耗;
  • 然后,既然穷举出了所有的可能集合,那么就能计算出每一个组合对应的价格和存库等信息,这样一来自然就可以形成一个字典了,无论选择了哪些组合,都能从这个字典上快速查询到对应的价格和库存等信息,即以空间换时间,只要在开始时初始化好了这个包含所有可能的数据字典,后续 sku属性的切换无非是字典 key的变化

当然了,思路是这个思路,但是真正写代码的时候,需要考虑的点比较多,而且都要考虑到,无论少了哪一点,数据就会都不对了

数据准备

假设对于手机这个品类来说,它的 sku属性有成色、颜色、配置、版本,其中成色分为 全新、仅拆封,颜色分为深空灰、银色、金色,配置分为64G256G,版本分为国行、港澳版、日韩、其他版本

每个 sku属性肯定都有自己独一无二的标识 ID,例如,对于颜色来说,它肯定有自己的 ID,称为 paramId,颜色下存在至少一个小属性,例如深空灰、银色、金色,每种颜色也都有自己的 ID,称为 valueId,结构如下:

interface ISkuParamItem {
   
  paramId: string
  paramValue: string
  valueList: Array<{
   
    valueId: string
    valueValue: string
  }>
}

请求 sku数据的时候,后端会将当前商品ID(称为 spuId)对应的所有sku属性返回,称为 sku属性数据集合数据格式暂定如下:

[{
   
    "paramId": "6977",
    "paramValue": "成色",
    "valueList": [{
   
        "valueId": "1081969",
        "valueValue": "全新"
    }, {
   
        "valueId": "1080699",
        "valueValue": "仅拆封"
    }]
}, {
   
    "paramId": "6975",
    "paramValue": "颜色",
    "valueList": [{
   
        "valueId": "730003",
        "valueValue": "深空灰色"
    }, {
   
        "valueId": "730004",
        "valueValue": "银色"
    }, {
   
        "valueId": "730005",
        "valueValue": "金色"
    }]
}, {
   
    "paramId": "7335",
    "paramValue": "配置",
    "valueList": [{
   
        "valueId": "710004",
        "valueValue": "64G"
    }, {
   
        "valueId": "710006",
        "valueValue": "256G"
    }]
}, {
   
    "paramId": "72",
    "paramValue": "版本",
    "valueList": [{
   
        "valueId": "1080627",
        "valueValue": "国行"
    }, {
   
        "valueId": "1080628",
        "valueValue": "港澳版"
    }, {
   
        "valueId": "1080697",
        "valueValue": "日韩"
    }, {
   
        "valueId": "1080629",
        "valueValue": "其他版本"
    }]
}]

当前商品ID(称为 spuId)对应的所有 sku数据返回,称为 商品全sku数据集合 数据格式暂定如下:

[
  {
   
      count: 98,
      paramIdJoin: "72_1080697__6975_730004__6977_1081969__7335_710006",
      priceRange: [7000, 8978],
      spuDId: "98002993445"
  }
]

其中,paramIdJoinsku属性组合连接而成,可分为 72_1080697、6975_730004、 6977_1081969、 7335_710006这个四个单元,每个单元又由 paramIdvalueId 连接而成,所以 72_1080697__6975_730004__6977_1081969__7335_710006的意思就是 版本为日韩、颜色为银色、成色为全新、配置为256Gsku组合,对应的总库存 count98,价格范围为 7000 ~ 8978,即最低价是 7000,最高价是 8978(如果只有一个价格没有高、低价格之分,那数组中的项就是那一个价格就行了),spu的标识 id spuDId98002993445

需要注意的是paramIdJoin 的值,例如72_1080697__6975_730004__6977_1081969__7335_710006,必须是按照 paramId进行升序(或者降序也可以,这里按照升序处理)进行连接的,72 < 6975 < 6977 < 7335,所以才有 72_1080697__6975_730004__6977_1081969__7335_710006这个拼接方式

这对于后续算法的优化有着显著的作用,不按照顺序也可以,但在数据量比较大的情况下,计算时间会比较长,很可能出现页面卡顿的情况

后端可能返回的数据结构和上面不一样,不过关系不大,无论后端返回的数据结构是什么样的,返回的信息肯定需要包括上面那些,因为这些都是必要数据,如果不一样,你只需要先行处理一下,处理成和上面一样的数据结构就行了,这是肯定可以做到的
有了上述数据,就可以开始写核心的处理代码了

分析思路

其实这里的功能就两个,那就是当选中或取消任意 sku属性的时候:

  • 计算出此时 sku属性组合对应的价格和库存
    例如当前选中了颜色:银色、内存:64G、运营商:移动,这一组 sku属性对应的商品的价格和库存

  • 计算出在此时的 sku属性组合之下,需要置灰哪些 sku组合
    例如当前选中了颜色:银色、内存:64G,这一组 sku属性的时候,剩下的哪些 sku属性与这两个已经选中的 sku组合后的组合库存为 0,则说明这些 sku属性应该要被置灰࿰

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值