为了账号安全,请及时绑定邮箱和手机立即绑定

[工作中遇到的难点] 数组去重算法高级应用

标签:
算法

今天在做需求的时候遇到了一个问题。有一堆产品对象放在一个数组arrs里,每个对象都有imageUrl,brand(产品品牌),name(产品名称),dimension(产品规格),quantity(产品数量,可能是面积和个数),id,type(根据位置分类),unit(单位),conpouType(产品套餐类型)等属性;
要求把imageUrl,brand,name,dimension等属性相同的产品给合并并显示到界面上,但是在判断两个产品是否相等的时候,不能把有些属性比如quantity,type进行比较。
展示到界面上的产品如图:


webp

产品展示.png

其中unit可能是 ‘个’,‘面积’,当unit是个的时候quantity只可能是1。

刚拿到这个需求,想到javascript经典的去重算法。就开始用算法复杂度最低的去重算法思路来实现这个需求。

大致思路:

1.根据产品id,name,先排序;
2.把arrs中的产品对象排完序后,for循环数组arrs,每次循环都要判断相邻两个对象是否深度相等(有的属性可能也是对象)。如果相等,就把两个对象的quantity相加,否则就不做处理。

咋一看,好像思路挺简单的,实现起来应该也没什么问题。
可是我忽略了我们程序中复杂多变的情况。

坑1:

有的产品没有产品id:测试去测的时候发现,总是出现相同,最后发现有的产品竟然没有id,经过考虑,个人觉得还是通过id判断比较合适,可是又没有其它字段可以代表没有id的产品。后来发现可以name在这个问题上有一定的决定权,所以就先用id来判断,如果没有id,再用name来判断。

坑2:

先用id再用name,看起来简单,在实现的时候还是犯了致命的错误。
如下代码,咋一看,好像没问题,实际上,问题大了

        contents.sort((a, b) => {          if(a.Id) {            if(a.Id > b.Id) return 1;            if(a.Id< b.Id) return -1;            if(a.Id=== b.Id) return 0;            
          } else {            if(a.name > b.name) return 1;            if(a.name < b.name) return -1;            if(a.name === b.name) return 0;
          }
        });

在发布前夕,又遇到相同类型的没有合并的问题,这次更神奇,生产上是错的,测试环境是对的。
看来是数据的问题,调了下代码,发现生产和测试环境的数据顺序不一样,仔细看了下上述排序过程,发现少判断了b.Id是不是存在的。如果a.Id存在,b.Id不存在,并且和b.Id不存在的这个产品相同的其它产品,都是用name排的序,它自己用Id排的序,不出问题才怪。

坑3:

上述算法===写成了=

坑4:

属性值有错,同一个属性的值,有的是[],有的竟然是undefined,于是找了数据来源方,控制数据类型的一致性。

坑5:

没有把type类型,剔除出去,结果在比较对象是否相等的时候,相同name的有好多type是不相等的。
于是我想了一馊主意。先根据产品Id或者name排序,排完序后,再根据产品type排序。当时的我一定没睡醒。

       contents.sort((a, b) => {          if(a.Id && b.Id) {            if(a.Id > b.Id) return 1;            if(a.Id< b.Id) return -1;            if(a.Id=== b.Id) return 0;            
          } else {            if(a.name > b.name) return 1;            if(a.name < b.name) return -1;            if(a.name === b.name) return 0;
          }
        });

       contents.sort((a, b) => {          if(a.type) {            if(a.type > b.type) return 1;            if(a.type < b.type) return -1;            if(a.type === b.type) return 0;            
          }
        });

毋庸置疑,这次测试又报bug了。
调了下代码,发现有两个问题,一个问题是有的产品name可能是空字符串,倘若如此,那不如不显示这些产品。于是去说服了测试,产品。
另一个问题是本来排的好好的序,name相同的为一组,再用type来排序,把name相同,type不同的类型活生生地拆散。然而,type并不是是否要合并产品的关键字段。所以这才把type从之前的比较对象的数组中剔除了,管它相不相等,按照name不为空的逻辑,正常排序就好。在后面合并的过程中,type不等,name和其它有必要比较的属性都相等相同就可以合并了。

总结:

这些bug集中在排序算法上,也怪我平时对这个算法理解的不够深入,总是想当然。倒是排序后的去重算法,没有出现过多的bug,看来平时刷的算法题还是有用的,关键时刻能减少bug。

带着对自己的谴责和对公司代码的无奈写完了这篇文章。只能说,革命尚未成功,同志仍需努力。



作者:向布谷鸟说早安
链接:https://www.jianshu.com/p/8d3c63b7c661


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消