SKU规格选择算法

实现目标

这里举一个例子来说明
在这里插入图片描述

											图一

现在有这一些规格可以供我们选择,但是这其中只有少部分规格是存在的,其他的规格是不存在的(这里还应该包括可销售商品数量为零的情况),不存在的规格不应该让用户可选中。以下为可以选择的规格

{"sku_list":[
		[
			"specs":[
				{key_id: 1, key: "颜色", value_id: 45, value: "金属灰"},
				{key_id: 3, key: "图案", value_id: 9, value: "七龙珠"},
				{key_id: 4, key: "尺码", value_id: 14, value: "小号 S"}
			]
		]
		[
			"specs":[
				{key_id: 1, key: "颜色", value_id: 42, value: "青芒色"},
				{key_id: 3, key: "图案", value_id: 10, value: "灌篮高手"},
				{key_id: 4, key: "尺码", value_id: 15, value: "中号 M"}
			]
		]
		[
			"specs":[
				{key_id: 1, key: "颜色", value_id: 42, value: "青芒色"},
				{key_id: 3, key: "图案", value_id: 11, value: "圣斗士"},
				{key_id: 4, key: "尺码", value_id: 16, value: "大号  L"}
			]
		]
		[
			"specs":[
				{key_id: 1, key: "颜色", value_id: 44, value: "橘黄色"},
				{key_id: 3, key: "图案", value_id: 9, value: "七龙珠"},
				{key_id: 4, key: "尺码", value_id: 14, value: "小号 S"}
			]
		]
	]
}
											代码片段一

比如用户选择颜色为金属灰,那么图案只有七龙珠可选,尺码只有小号 S可选,其他颜色和尺码都不应该可以选择,如下图所示
在这里插入图片描述 图二
同时还应该考虑反选的情况,比如这里已经选择了金属灰,如果用户取消金属灰,那么颜色、图案、尺码应该变为全部可以选择。说完了最终实现的效果,下面再看看具体的实现思路

实现思路

一、获取数据,计算可选规格

服务器提供的数据可能只是上面例子中代码片段一那样,这时就需要整理,这里我整理结果如下(根据自己的实际情况处理),其中select_type表示用户的选择状态(unselected表示未选中,selected表示选中,locking表示不可选中),因为是初始值,所以默认都应该是可以选中,把整理的数据渲染到页面上,如图一

[
	{
		key: "颜色",
		key_id: 1,
		value: [
			{value: "金属灰", value_id: 45, select_type: "unselected"},
			{value: "青芒色", value_id: 42, select_type: "unselected"},
			{value: "橘黄色", value_id: 44, select_type: "unselected"}
		]
	},
	{
		key: "图案",
		key_id: 3,
		value: [
			{value: "七龙珠", value_id: 9, select_type: "unselected"},
			{value: "灌篮高手", value_id: 10, select_type: "unselected"},
			{value: "圣斗士", value_id: 11, select_type: "unselected"}
		]
	},
	{
		key: "尺码",
		key_id: 4,
		value: [
			{value: "小号 S", value_id: 14, select_type: "unselected"},
			{value: "中号 M", value_id: 15, select_type: "unselected"},
			{value: "大号  L", value_id: 16, select_type: "unselected"}
		]
	}
]
												代码片段二

二、处理用户点击事件

1、已选中的规格

当用户点击其中一个规格,先将已经选中的规格保存起来。如果是选中,则将保存起来的规格中相同key_id的数据先删除,然后再将新的插入,如果是反选,则直接删除就好,具体的实现如下

 let skuStatus = this.data.skuStatus.concat()
 if (skuStatus.length > 0) {
     skuStatus = skuStatus.filter((value, key, arr) => {
         return value.key_id != key_id
     })
 }
 if (select_type == "unselected") {
     skuStatus.push({
         "key_id": key_id,
         "value_id": value_id
     })
 }
 this.setData({
     skuStatus
 })
												代码片段三

2、循环规格列表

保存完当前选中的规格后,再来循环代码片段二的内容(这里只是一种实现情况,按照具体情况实现具体循环),因为循环体里面的内容太多,下面给一段伪代码

外层循环{
	内层value循环{
		if(key_id和value_id是否在选中状态中存在)
			存在,将对应的select_type设置为selected
			不存在,这种情况必较复杂,单独拿出来分析
	}
}

以下为不存在的情况处理办法

1、把保存的选中状态拿出来,赋值给newStatus
2、如果newStatus中包括外循环的key_id,
	则先将其删除,再将循环体内的key_id和value_id添加到newStatus,这一步很重要,
	let newStatus = skuStatus.concat()
	newStatus = newStatus.filter((value, key, arr) => {
	    return value.key_id != spec.key_id
	})
	newStatus.push({
	    "key_id": spec.key_id,
	    "value_id": specValue.value_id
	})
3、下面就将newStatus当作是已选中的状态,
	把这个新的状态和可以选择的规格(代码片段一)去比较,
		比较结果为true则表明这种状态可选,将对应的select_type设置为unselected,
		如果为false,则表明这种状态不可选,将对应的select_type设置为locking

再来看看newStatus和代码片段一的对比过程,这里也需要采用循环

定义一个空数组skuSpecsFalg
外循环,循环代码片段一sku_list{
	定义一个空数组flag
	内循环,循环newStatus{
		判断sku_list下面的specs是否包含内循环的key_id和value_id
		存在将true添加到flag数组,不存在将false添加到flag数组并退出内层循环
	}
	判断flag中是否存在false,
	存在将false添加到skuSpecsFalg,不存在将true添加到skuSpecsFalg中并退出整个循环
}
判断skuSpecsFalg是否包含true,包含则返回true,否则返回false

提示:下面代码中,循环体里面的return false并不会结束整个函数,只是结束当前循环
 let skuSpecs2 = []
 skuList.some((skuListV, skuListI, skuListA) => {
     let flag = []
     status.some((value, index, arr) => {
         let vIndex = skuListV.specs.findIndex((v) => v.key_id == value.key_id && v.value_id == value.value_id)
         if (vIndex != -1) {
             flag.push(true)
         } else {
             flag.push(false)
             return false
         }
     })
     // console.log(flag)
     if (flag.findIndex((v) => v == true) == -1) {
         skuSpecs2.push(true)
         return false
     } else {
         skuSpecs2.push(false)
     }
 })

 if (skuSpecs2.findIndex((v) => v == true) != -1) {
     return true
 } else {
     return false
 }

这里的对比过程比较复杂,举个例子来说明一下,比如现在的newStatus如下

[
	{key_id:1,value_id:44},
	{key_id:3,value_id:9}
]

那么这里就应该判断的数组的两个元素是否在sku_list其中一个specs中都存在,再次强调,这里必须是其中一个specs包含数组中的两个元素,这样才可以保证这种状态是可以选中,这种规格才算是存在的。这里只要有一个specs满足这一的条件,则表明这种newStatus是可选的,如果全部specs都不满足,才表明newStatus是不可选的*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值