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. ~分隔目标和 ...
随机推荐
- libevent(十三)evhttp事件处理流程
在libevent(六)http server中,作为一个单线程http server,不仅要监听每个连接的到来,还要监听每个连接上的I/O事件. 查看源码可知,在evhttp_bind_socket ...
- Node.js中模块加载机制
1.模块查找规则-当模块拥有路径但没有后缀时:(require(‘./find’)) require方法根据模块路径查找模块,如果是完整路径,直接引入模块: 如果模块后缀省略,先找同名JS文件,再找同 ...
- JAVA设计模式之单例(singleton)
一.饿汉式 /** * 饿汉式 */public class Singleton01 { private static final Singleton01 instance = new Singlet ...
- 【Spark】一张图看懂Spark的运行架构,以standAlone模式为例
- 【Hadoop离线基础总结】Hadoop High Availability\Hadoop基础环境增强
目录 简单介绍 Hadoop HA 概述 集群搭建规划 集群搭建 第一步:停止服务 第二步:启动所有节点的ZooKeeper 第三步:更改配置文件 第四步:启动服务 简单介绍 Hadoop HA 概述 ...
- Adobe Reader XI 打开后“已停止工作”的解决办法
搜了好多方法按照步骤做完,基本无用,试了以下方法搞定. 具体方法是: 把域名解析到本机. 打开 C:\Windows\System32\drivers\etc\hosts 添加 127.0.0.1 a ...
- 【hdu1024】简单dp
http://acm.hdu.edu.cn/showproblem.php?pid=1024 最大m字段和,题目就不多说了,经典dp 这题坑爹...首先不说明m的范围(n<=1000000),还 ...
- [hdu5203]计数水题
思路:把一个木棍分成3段,使之能够构成三角形的方案总数可以这样计算,枚举一条边,然后可以推公式算出当前方案数.对于已知一条边的情况,也用公式推出.用max和min并维护下,以减少情况数目. #prag ...
- [zoj3632]线段树的应用
题意:f[i] = min(f[i+L]~f[i+R]) + x,计算f数组.从大到小计算即可,用线段树维护一下. #pragma comment(linker, "/STACK:10240 ...
- 09JAVA基础-常用类
1.Scanner //获取键盘输入 Scanner sc = new Scanner(System.in); int num = sc.nextIn(); String str = sc.nextL ...