简体   繁体   English

使用javascript有效地搜索字符串数组中的字母

[英]Search alphabets in array of string efficiently using javascript

I have an array of products as below我有一系列产品如下

const totalProducts = ['washing machine', 'sewing machine', 'refrigerator', 'desk']

If a user types any word on the input field, i want to get all matching products from the array.如果用户在输入字段中键入任何单词,我想从数组中获取所有匹配的产品。 for eg if user types 'ma', then i would expect the result to contain ['washing machine', 'sewing machine']例如,如果用户键入“ma”,那么我希望结果包含['washing machine', 'sewing machine']

In order to achieve the desired result, i do this code below为了达到预期的结果,我在下面执行此代码

var result = totalProducts.filter((product) => product.includes('ma'));

I know this above code works to get the desired result.我知道上面的代码可以得到想要的结果。 but suppose the totalProducts array has a length of over 1000. Will my method above efficiently give the result as it should ?但假设 totalProducts 数组的长度超过 1000。我上面的方法会有效地给出它应该得到的结果吗?

Or is there a better way to search and improve performance of my code ?还是有更好的方法来搜索和提高我的代码性能?

Since .filter() and .includes() are both constant time (o(n)), the total time complexity is O(2n).由于.filter().includes()都是常数时间 (o(n)),因此总时间复杂度为 O(2n)。

The only way I can think of to improve the performance of the code would be to cache (or otherwise store) the filtered results array, and then further filter that array unless the user backspaces.我能想到的提高代码性能的唯一方法是缓存(或以其他方式存储)过滤后的结果数组,然后进一步过滤该数组,除非用户退格。

sometimes when your data is too large you run out of possibilities to obtain more efficient methods, what i suggest is to actually filter your data in your backend and add a spinner as a visual feedback for the user.有时当您的数据太大时,您将无法获得更有效的方法,我建议在后端实际过滤您的数据并添加微调器作为用户的视觉反馈。 also debouncing you onKeyDown listener should be used to avoid flooding your server with http requests for each key press.还应该使用 onKeyDown 侦听器去抖动,以避免每次按键都用 http 请求淹没您的服务器。

It is a tradeoff between space and time.这是空间和时间之间的权衡。 There is indeed a faster approach, but the array needs to be processed beforehand to build an index, which takes up memory.确实有更快的方法,但是需要事先处理数组建立索引,占用内存。 If you build a suffix tree with an index of each string in a leaf, you can simply find the appropriate subtree and enumerate all the indices contained in it.如果您使用叶子中每个字符串的索引构建后缀树,您可以简单地找到适当的子树并枚举其中包含的所有索引。

Let me use a smaller example, for the sake of size in this answer.为了这个答案的大小,让我使用一个较小的例子。 Assume you have "pit,spit,pot,spot".假设你有“pit,spit,pot,spot”。 A suffix tree of those strings is这些字符串的后缀树是

后缀树

(Thanks to this site for the visualisation.) If you want to find the strings that contain "po", starting from the root, take the "p" node, then the "o" node (here collapsed into the "ot$" node). (感谢这个网站的可视化。)如果你想找到包含“po”的字符串,从根开始,取“p”节点,然后是“o”节点(这里折叠成“ot$”节点)。 The subtree under it contains links to strings #3 and #4 (this site indexes them from 1), ie "pot" and "spot".它下面的子树包含指向字符串#3 和#4 的链接(这个站点从1 开始索引它们),即“pot”和“spot”。 (This site also notes that the substring starts at position 1 for "pot" and position 2 for "spot", but for your purpose this information is not required.) (该站点还指出,“pot”的子字符串从位置 1 开始,“spot”的子字符串从位置 2 开始,但出于您的目的,此信息不是必需的。)

As you can see, the process of finding the matching strings is very fast;如您所见,查找匹配字符串的过程非常快; but the requisite suffix tree would be much larger than the original list.但必要的后缀树会比原始列表大得多。 If you want to restrict the search to only match the start of words (for example, "ma" would match "washing machine", but "chi" would not), you could reduce the tree size.如果您想将搜索限制为仅匹配单词的开头(例如,“ma”将匹配“washing machine”,但“chi”不会),您可以减小树的大小。

However, the gains would, for most purposes, be negligible for a single search;但是,对于大多数目的,单次搜索的收益可以忽略不计; this would probably only be needed if you need to perform the search repeatedly, fast.这可能仅在您需要快速重复执行搜索时才需要。 For an array of thousands of elements and a single lookup once in a while, your original approach is almost certainly good enough.对于数千个元素的数组和偶尔的一次查找,您的原始方法几乎可以肯定足够好。 The suffix tree approach is faster, but for the use case in the OP, an overkill, and a case of premature optimisation.后缀树方法更快,但对于 OP 中的用例来说,这是一种矫枉过正和过早优化的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM