sku算法介绍及实现
前言
做过电商项目前端售卖的应该都遇见过不同规格产品库存的计算问题,业界名词叫做sku(stock Keeping Unit),库存量单元对应我们售卖的具体规格,比如一部手机具体型号规格,其中iphone6s 4G 红色就是一个sku。这里我们区别spu(Standard Product Unit),标准化产品单元,比如一部手机型号iphone6s就是一个spu。
sku 算法
在前端展示商品时,根据用户选择的不同sku,我们需要计算出不同的库存量动态展示给用户,这里就衍生出了sku算法。
数据结构
我们先看看在后端服务器保存库存的数据结构一般是长怎么样的:
// 库存列表
const skuList = [
{
skuId: '0',
skuGroup: ['红色', '大'],
remainStock: 7,
price: 2,
picUrl: 'https://dummyimage.com/100x100/ff00b4/ffffff&text=大'
},
{
skuId: '1',
skuGroup: ['红色', '小'],
remainStock: 3,
price: 4,
picUrl: 'https://dummyimage.com/100x100/ff00b4/ffffff&text=小'
},
{
skuId: '2',
skuGroup: ['蓝色', '大'],
remainStock: 0,
price: 0.01,
picUrl: 'https://dummyimage.com/100x100/0084ff/ffffff&text=大'
},
{
skuId: '3',
skuGroup: ['蓝色', '小'],
remainStock: 1,
price: 1,
picUrl: 'https://dummyimage.com/100x100/0084ff/ffffff&text=小'
}
];
// 规格列表
const skuNameList = [
{
skuName: "颜色",
skuValues: ["红色", "蓝色"]
},
{
skuName: "尺寸",
skuValues: ["大", "小"]
}
];
算法演示
在前端用户选择单个规格或多个规格后,我们需要动态计算出此时其他按钮是否还能点击(组合有库存),以及当前状态对应的总库存量,封面图和价格区间。
以上面的数据举个

开始时什么都没有选择,展示默认图片,规格列表中的第一项组合(['红色-大'])对应的图片,库存为商品总库存,价格为商品的价格区间。然后在用户选择某个属性或几个属性的时候实时计算对应的图片,库存,价格区间。
同时根据当前已选属性,置灰不可选择的属性。在本例中,蓝色 大的产品对应的库存为 0,所以当我们选择其中一项 蓝色 或者 大 的时候,需要置灰另一个属性选项。
实现思路-第一种算法
为了大家能看清下面的分析,在此定义下相关名词,库存列表:skuList,规格列表:skuNameList,属性:skuNameList-skuValues数组下的单个元素,规格:skuNameList下的单个元素
sku 算法的难点在于如何根据当前已选属性(未选,选择部分,全选)来判断当前其它属性是否可选
在网上查找相关算法时比较广泛流传的是来自淘宝前端的两种算法,下面将实现第一种算法:
主要思路就是遍历当前的规格列表下的属性,根据已选属性及库存列表判断当前属性按钮是否有库存(可选):
将规格列表下的已选属性集合作为入参
selected,如果在当前规格未选择相关属性则传入空字符串,即最开始时selected === ['', '']初始化相关变量,库存,价格区间,图片,及属性对象
attrState(attrState 用于标记每个属性是否可选)遍历规格列表,移除存在与当前规格属性数组中已选属性(假设当前规格未选择)
遍历规格属性,依次将当前属性和已选属性组合
将上步的组合作为最终属性组合,遍历库存列表是否存在库存(属于子集关系且库存>0),有库存则标记可选(true)
最后再次遍历库存列表,用来获取当前库存,图片,价格等 sku 数据
/**
* 获取sku信息
* @param {Array} selected 已选属性数组
* @return {Object} skuInfo
*
*/
const getSkuInfo = (selected) => {
// 用以记录每个按钮状态的,例如 itemState['红色'] = true 表示高亮
const attrState = {};
let picUrl = '';
let minPrice = Number.MAX_VALUE;
let maxPrice = 0;
let remainStock = 0;
// in array not in others
const difference = (array, others) => {
return array.filter((item) => others.indexOf(item) === -1);
};
// every in array in others
const isSubset = (array, others) => {
return array.every((item) => others.indexOf(item) > -1);
};
// 遍历规格列表
skuNameList.forEach((spec) => {
// 移除当前遍历规格下的已选属性
const tempSelected = difference(selected, spec.skuValues).filter(name => name);
// 遍历规格属性
spec.skuValues.forEach((name) => {
const willSelected = [...tempSelected, name];
// 默认无库存不可选
attrState[name] = false;
// 在库存列表寻找匹配库存
for (let i = 0, len = skuList.length; i < len; i++) {
const skuGroup = skuList[i].skuGroup;
if (isSubset(willSelected, skuGroup) && skuList[i].remainStock) {
attrState[name] = true;
break;
}
}
});
});
// 实际已选属性,过滤空字符串
const realSelected = selected.filter((item) => item);
// 默认选择用于匹配当前图片
const defaultSelected = selected.map(
(name, idx) => name || skuNameList[idx].skuValues[0]
);
skuList.forEach((sku) => {
if (isSubset(realSelected, sku.skuGroup)) {
remainStock += sku.remainStock;
maxPrice = maxPrice > sku.price ? maxPrice : sku.price;
minPrice = minPrice < sku.price ? minPrice : sku.price;
// 取当前图片
if (isSubset(defaultSelected, sku.skuGroup)) {
picUrl = sku.picUrl;
}
}
});
return {
attrState,
picUrl,
minPrice,
maxPrice,
remainStock,
};
};
总结
做过电商项目的应该都处理或者听说过sku,学习相关概念和真正理解如何计算sku可以帮助我们更加熟悉业务,提升自己对于相关业务的处理能力。以后在面试中遇到面试官的提问也能更稳一些。后面将介绍第二种算法,其思路更容易理解,也是比较多同学在业务中采用的方式。
参考
欢迎到前端学习打卡群一起学习~516913974
sku算法介绍及实现的更多相关文章
- 【原创】机器学习之PageRank算法应用与C#实现(1)算法介绍
考虑到知识的复杂性,连续性,将本算法及应用分为3篇文章,请关注,将在本月逐步发表. 1.机器学习之PageRank算法应用与C#实现(1)算法介绍 2.机器学习之PageRank算法应用与C#实现(2 ...
- KNN算法介绍
KNN算法全名为k-Nearest Neighbor,就是K最近邻的意思. 算法描述 KNN是一种分类算法,其基本思想是采用测量不同特征值之间的距离方法进行分类. 算法过程如下: 1.准备样本数据集( ...
- ISP基本框架及算法介绍
什么是ISP,他的工作原理是怎样的? ISP是Image Signal Processor的缩写,全称是影像处理器.在相机成像的整个环节中,它负责接收感光元件(Sensor)的原始信号数据,可以理解为 ...
- Python之常见算法介绍
一.算法介绍 1. 算法是什么 算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输 ...
- RETE算法介绍
RETE算法介绍一. rete概述Rete算法是一种前向规则快速匹配算法,其匹配速度与规则数目无关.Rete是拉丁文,对应英文是net,也就是网络.Rete算法通过形成一个rete网络进行模式匹配,利 ...
- H2O中的随机森林算法介绍及其项目实战(python实现)
H2O中的随机森林算法介绍及其项目实战(python实现) 包的引入:from h2o.estimators.random_forest import H2ORandomForestEstimator ...
- STL 算法介绍
STL 算法介绍 算法概述 算法部分主要由头文件<algorithm>,<numeric>和<functional>组成. <algorithm ...
- Levenshtein字符串距离算法介绍
Levenshtein字符串距离算法介绍 文/开发部 Dimmacro KMP完全匹配算法和 Levenshtein相似度匹配算法是模糊查找匹配字符串中最经典的算法,配合近期技术栏目关于算法的探讨,上 ...
- 机器学习概念之特征选择(Feature selection)之RFormula算法介绍
不多说,直接上干货! RFormula算法介绍: RFormula通过R模型公式来选择列.支持R操作中的部分操作,包括‘~’, ‘.’, ‘:’, ‘+’以及‘-‘,基本操作如下: 1. ~分隔目标和 ...
随机推荐
- Hadoop入门学习笔记-第二天 (HDFS:NodeName高可用集群配置)
说明:hdfs:nn单点故障,压力过大,内存受限,扩展受阻.hdfs ha :主备切换方式解决单点故障hdfs Federation联邦:解决鸭梨过大.支持水平扩展,每个nn分管一部分目录,所有nn共 ...
- react-redux的理解
react-redux是辅助redux的,我们正常使用redux是很麻烦的,需要在每个组件中去监听数据变化,执行数据更新等 但是通过react-redux,我们可以简化组件使用公共数据的操作, rea ...
- Kafka 的一些知识点整理【1】
First: Kafka 是什么? Kafka 是一个发布订阅系统 最初是是LinkedIn 开发 最后交给Apache 开源组织 github地址:https://github.com/apache ...
- 通过10个实例小练习,快速熟练 Vue3.0 核心新特性
Vue3.0 发 beta 版都有一段时间了,正式版也不远了,所以真的要学习一下 Vue3.0 的语法了. GitHub 博客地址: https://github.com/biaochenxuying ...
- 5.7.17版本mysqlbinlog实时拉取的二进制日志不完整的原因分析
问题描述: 同事使用mysqlbinlog工具的--read-from-remote-server --raw选项,从远程实例实时拉取二进制日志时,发现得到的二进制日志文件大小与远程实例上的源文件大小 ...
- elasticsearch kibana的安装部署与简单使用(二)
介绍一下elasticsearch和kibana的简单使用 es其实我理解为一个数据库,一个数据库无非就是增删改查, Delete PUT GET POST 这些接口关键字完美对应 比如,我想查一张 ...
- 设计模式之GOF23策略
策略模式strategy 场景:对不同客户的不同报价策略 如果采用if else不易扩展,不符合开闭原则,可以采用策略模式 策略模式: 对应于解决某一个问题的算法族,允许其中一个算法去解决某一问题,同 ...
- mybatis 新增返回id
第一种方式: 在实体类的映射文件 "*Mapper.xml" 这样写: <insert id="insertAndGetId" useGeneratedK ...
- 开源电影项目源码案例重磅分析,一套代码发布小程序、APP平台多个平台
uni-app-Video GitHub地址:https://github.com/Tzlibai/uni-app-video 一个优秀的uni-app案例,旨在帮助大家更快的上手uni-app,共同 ...
- MYSQL8 常用操作
开启root账号远程访问 方法1 mysql'; //修改密码认证方式为mysql_native_password mysql> GRANT ALL ON *.* TO 'root'@'%'; ...