转载

百度师傅按钮联动算法

最近转到了[百度师傅][ shifu ]团队,接受百度师傅的开发,刚开始就遇到一个不小的技术项目,本文简要记录下,备忘。

需求

先来简单介绍下需求,最终做出来的效果如下图所示,你其实可以来到百度师傅的服务详情页体验下最终效果(今天就会上线啦):

百度师傅按钮联动算法

上面的例子其实可以理解为三组单选按钮,只是这个单选按钮可以取消选中,三组必须全选中才能预约服务。

其中有些选项是不可选的,如上图,选中iphone4后,金色就不能选了。

整个按钮的信息,及按钮之间相互制约是否可选的信息都是从后端打过来了,这就需要我们有一组算法来在点击的时候实时计算当前按钮的点击情况。

技术选型

这个其实不是必须的,简单介绍下百度师傅的技术选型,jquery + baidutemplate 。

思路

一开始是没有思路的,我其实想到在js中维护一套,当前按钮状态的数据,每次按钮点击,计算按钮状态,然后重新渲染模版。

其实按钮状态->模版渲染是很简单的,难点在于计算按钮的状态。

数据结构

先来说下数据结构,其实主要用到四个数据结构。

buttonList

这个数据结构用来存放按钮的状态,上面例子中的数据结构片段如下:

"buttonGroup": [{  "variable": "type",  "text": "选择类型",  "list": [{   "value": 1,   "text": "iPhone 4",   "subText": ""   "status": 1   }, {    "value": 2,    "text": "iPhone 4s",    "subText": ""    "status": 1   }  ] }]  

其中大部分都是展现文案,和变量名称。

  • variable 当前按钮组的变量名
  • value 当前选中按钮的值

其中status用来存储按钮的状态:

  • 0 不可选
  • 1 可选
  • 2 选中

注意:value=1 不一定排在数组的第一个,value和数序无关,数组的顺序是按钮的展示顺序。

map

这个数据结构主要用来查找按钮在buttonGroup中的索引。上面例子中的按钮数据结构对应的map如下所示:

{  "type": {   index: 0,   vmap: {    1: 0,    2: 1   }  } }  

通过这个数据结构,我们拿到按钮的type就可快速找到这个type在按钮展示数组中的索引为0,通过当前选中按钮的值,比如iPhone 4被选中,其value为1,通过1可以在vmap中快读定位到其在buttonGroup中的索引为0。

wayList

这个数据结构用来存储可达的路径,典型的可大路径如下所示:

[{  "path": {   "type": 1,   "method": 1,   "color": 1  },  "price": 17900,  "regularPrice": 29900,  "stockout": false }]  

这个数据结构的意思代表,按钮组中对应的值可选中。

resultList

这个数据结构用来存储当前按钮的选中状态:

{     type: 1,     method: 2,     color: null } 

其中null代表未选中,数字代表选中按钮的值。

算法

  • 按钮点击,拿到当前各个按钮的选中状态
  • resultList取出一个属性,计算这组按钮的状态
  • 将当前组的值全部置为不可选
  • resultList中计算的属性置为null,计算可选路径
  • 将可选路径中,当前组的值全部置为可选
  • 将当前组中选中的按钮置为选中
  • 跳到第二步,知道每组按钮都计算过

看起来好晕的感觉,我们来举个例子吧:

比如上面的选中状态,第一组按钮值为1的被选中,第二组值为2的被选中,第三组未选中。

  1. 将type按钮全部置为不可选
  2. 将type设置为null
  3. 在wapList中遍历method为2的全部值
  4. 在遍历的结果中找到type的值,将对应的值置为可选
  5. 将type值为1的按钮置为选中

  6. method类似 。。。

  7. 将color按钮全部置为不可选
  8. 在wapList中遍历type为1,method为2的全部路径
  9. 在遍历的结果中,找到color的值,置为可选

总结

上面的算法还是可以改进的,有些数据结构可以省略,写了这么多年前端页面,第一次写这么复杂的逻辑,(/ □ /)。

最后做个广告,如果你有电脑除尘,重装系统,手机碎屏方面的需求,就来 百度师傅 吧。

正文到此结束
Loading...