如何实现对商品列表的排序?
如图所示,前端的界面是这样的,需求是:前端通过拖动商品完成对商品的排序。前端是有分页的,第二页的商品也可以拖动到第一页进行排序。
现在数据库中有sort字段,字段全部为0。目前商品列表是按照时间倒序排序的。
那么接口的排序算法应该如何设计?如果采用最小的代价去实现排序,同时尽量不去在添加和修改商品处做改动。
回答:
按照已有顺序更新 sort 列,并且给一个较大的间隙,比如每个产品之间的间隔为 1000,这就是原始间隙。
set @sort := 0;update product set sort=(@sort:= @sort+1000) order by id
每次当拖动排序产品到新位置时,计算新位置前后两个 sort 的中间值,然后作为新位置的 sort 值。
id | sort |
---|---|
1 | 1000 |
2 | 2000 |
3 | 3000 |
把 3
拖动到 1
跟 2
中间,那就把 3
的排序值改为 1000+(2000-1000)/2=1500
,也可以加点儿随机数,让其不那么均匀。
id | sort |
---|---|
1 | 1000 |
3 | 1500 |
2 | 2000 |
每次拖动时都这样,当然,拖动次数多了以后,就还是可能会出现,无法再继续分了,这时候就可以又根据当前的顺序,去重排间隙。
set @sort := 0;update product set sort=(@sort:= @sort+1000) order by sort
大概就是这样吧
回答:
这样说我就理解你的问题了,这个问题其实不难,其实把数组转变成链表就可以了。
起始的状态如下,sort 里面放的是链表下一环的 id
id | name | sort |
---|---|---|
1 | xx | 2 |
2 | xx | 3 |
3 | xx | 4 |
4 | xx | 5 |
5 | xx | 0 |
当你把 4 拖到 2 前面的时候,变成如下状态
id | name | sort |
---|---|---|
1 | xx | 4 |
2 | xx | 3 |
3 | xx | 5 |
4 | xx | 2 |
5 | xx | 0 |
每次拖动的时候只需要修改:
- 原来指向自己的条目 (这里是 3,把 4 改成 5)
- 将要指向自己的条目 (这里是 1,把 2 改成 4)
- 自己将要指向的条目 (这里是 4,把 5 改成 2)
每次拖动只需要改动3条数据。
排序的时候,最好有个额外的地方记录第一个条的 id,这样不停的 next 就可以了,不记录也可以,但处理起来可能会麻烦一点。
回答:
考虑使用场景,我认为采用数组调整顺序修改下标那样,批量修改排序即可
原因:
1、这种使用场景下,用户拖动的范围不会很大,几十个了不起,就算几百个,后端批量更新几百条数据的排序字段也并非不可接受的性能损耗,每次批量更新,事务管理,失败还是成功,也不会导致额外的影响
2、采用比如一楼的方法,确实是一种巧妙的解决方案,但是本身引入了其他额外的复杂处理,代码上变复杂,逻辑上也变复杂,并不易于维护以及可能引入新的问题
当然要根据具体的业务场景考虑,用户量不大,修改不会很频繁的场景下,我认为采用这种简单直接的方式更加合理
回答:
sort字段修改成double类型
sort 按顺序1,2,3,4,5排序
每换一次顺序,将前后两者的除以2的结果作为新的sort
考虑到精度的问题,这个方案是存在问题的
还有一种方法
sort字段还是按照1,2,3...排序
前端能判断出用户移动商品的跨页数的话,比如从第五页移动到第一页
那么就把前五页的商品数据全部传递给后端,后端按照前端传递商品数据的顺序,生成sort顺序
这样只需要修改前五页的数据,批量修改有可能会遇到唯一索引的问题(我遇到过,场景不仔细描述),可以删除前五页的数据,再新建前五页的数据(简单粗暴)
极限情况:用户把最后一页的商品拖拽到第一页,那么就需要修改全部数据
处理方式:可以对用户的拖拽商品移动的页数进行限制
以上是 如何实现对商品列表的排序? 的全部内容, 来源链接: utcz.com/p/938691.html