求解,在对象数组中如何快速的检索出自己想要的数据?
发布于 6 年前 作者 orangeChu 5167 次预览 最后一次回复是 6 年前 来自 问答
RT,目前做了个小项目,数据源是几千到一万的通讯录数据,对象包含姓名、电话、住址之类balabala的信息。 想要对这些数据做检索,目前做法是把这些数据后台load出来成对象数组,放在页面的变量上,使用filter、set等方式来进行检索。但是给我的感觉,就几千到一万的对象数组,检索都要花费1s左右的时间。加了loading动画后,慢的感觉特别明显。 所以求问,有什么方法能更加快速的检索?望不吝赐教,先谢过~
18 回复
第一种是让后台服务端提供需要的数据,或者自己写node请求他的接口然后检索返回给前端,服务端肯定比客户端要快些。 第二种可以使用lodsh这个模块,针对json有很多方法,总有种适合你
@tzbcf 感谢回复。 1、后端基于express搭建,尝试过这种方式,发现速度上,没有明显的提升; 2、试过lodsh的filter,速度上跟es的filter不相上下;
贴个我写的豆腐渣(编辑器支持markdown吗?):
几千到一万的通讯录数据,这应该是一份固定的数据。既然是固定的。我觉得两个方法 1.如果只用某个关键词来检索,将数组变成object,用你的关键词做key如{“手机号码”:{xxxx}},这样利用js本身的特性。速度飞快。 2.如果有多个关键词,则做简单的索引。同样利用object特性。{“手机号码”:[1,2,3],“姓名”:[3,4,5]},1,2,3 3,4,5为对象在数组中的位置。
实在复杂,你就做索引,然后排序,然后用双叉树来检索
@pzzcn 先赞美大佬的回答。:) 是的,数据是固定的。 您的建议听起来比我的方法好多了。 没有这方面的经验,问两个不成熟的问题: 1、每次的搜索词都要做一次索引吗? 2、索引需要存储吗?是否每次搜索都要重新做索引,然后根据索引取出对应的对象?
数据固定的,将数组先做好索引,存储起来。下次直接使用索引来查找数据
@pzzcn 再次感谢。。 类似索引的实现有demo参考吗?不胜感激
@orangeChu 这个没有哦
@pzzcn 好的! 根据您提供的思路,我大概写了一版。 根据查询的字段长度,进行拆分,最大值为12,构建12个对象,类似{0:{“a”:[0,1],“b”:[0,1]…}} 通过搜索的关键字的长度和关键字,得到对象下标数组,最后得到值。类似
indexes[关键字长度][关键字]得到对象下标数组,最后循环下标数组,得到结果。 但是这样处理后,运行的结果对比(数据量在2500左右),比for循环、filter过滤来得慢?贴一下方法的最后运行代码,前面处理索引的没啥好看的,处理索引的时间不在结果比较中:
@orangeChu 这样对比不合适的,因为没有考虑引擎的 JIT 功能。如果没有 JIT 的话,filter 处理的时候因为需要调用回调,肯定有 JMP,而 forloop 的实现,可以看成是 inline 版的 filter,这已经会导致 forloop 比 filter 快一点了。所以要对比实际执行情况的话,最好是先将函数热身,然后再对比执行结果。
@hsiaosiyuan0 收到!(不好意思,昨晚蹦迪去了,没注意看到您的回复。 按照您的建议,函数执行前进行热身,以下是测试结果(编写的方法居然更快了!):
@iceyang
感谢您的回复。 主体是通过
electron来做加载的,主进程中已经将数据从数据库加载出来了,使用buffer存储。渲染进程获取该数据后,放在变量中进行操作,操作的同时缓存一份数据到localforage中,之后获取localforage中的缓存数据,不再重复获取主进程中的数据源。为啥我是一次性加载所有数据,而不是需要时再查询? 我是这么考虑的:暂时使用
nedb来做数据的存储。使用时再去查询数据,文件的io流,要消耗不少时间,所以我的做法是一次性加载所有数据,并且这些数据不需要实时更新,这样做我认为会有比较好的体验。 如果大伙有比较好的建议,我会认真考虑一下。先谢过~为啥cnode的编辑器,加了
---后,会自动粗体上面的文字,我该怎么编辑才能取消粗体呢?@orangeChu markdown 中的 — 是会将上面的文字变成把标题的。
不好意思前面的回复被我不小心删了。所以就变成你在回复空气了:-D
是这样的,对于筛选这件事,我认为用js做不太合适,既然你的数据源是数据库,那么是可以通过数据库索引最大速度来做这个筛选动作的。
另外是这么多条数据你是在一页就展示了全部吗。
@iceyang 感谢回复。
nedb的索引以及查询,发现效果不怎么理想,所以才改为这种方案来实现。搜索需求是关系型数据库的基本功能。
@waitingsong 感谢回复。 之前试过使用主进程来做搜索,然后返回,发现效果一般,也许我该让渲染进程直接查询。
@orangeChu 少量数据的特定字段的检索这个可以在前端实现,这个叫做缓存。 这么多数据并且检索多个字段,你是想自己实现一个精简版数据库么?
@waitingsong 哈哈,您说的是对的。 前端的做法就是把数据都
load出来,然后检索。 dammit,我一个写后端的好像被传染了。 马上改正。