用另一个过滤一个数组 [英] Filter one array with another
问题描述
我知道这个问题已经被回答了多次,但是我似乎无法根据自己的情况找到答案。我有两个数组:
words ['word1','word2','word3']
文本[
{名称:'blah',描述:'word4'},
{名称:'blah2',描述:'word1'},
{名称:'blah3',描述:'word5 '}
]
我试图过滤两个数组,如果有则返回true匹配
我见过一些简单的数字数组示例,但不适用于此处。
您可以使用 Array.prototype.some()
并检查<$ c $中的匹配项c>单词使用 Array.prototype.includes()
。如果个单词
和个文本
的长度为 n <,这就是O(nm)的时间复杂度。 / code>和
m
。
const单词= ['word1','word2','word3'] const文本= [{{名称:'blah',描述:'word4'},{name:'blah2',描述:'word1'},{名称:'blah3',描述:'word5'}] console.log(texts.some(({description})=> words.includes(description)))
另一种时间复杂度为O(n + m)的解决方案使用 Set.prototype.has()
代替,但是如果 words
是一个小数组,这种方法可能会更快甚至更慢一些,所以仅如果个单词
很大,则使用此选项。
常量单词=新Set([['word1','word2','word3']))常量文本= [{名称:'blah',描述:'word4'},{名称:'blah2',描述:'word1'},{名称:'blah3',描述:'word5'}] console.log(texts.some(({description})=> words.has(description)))
更新
要解决有关区分大小写的问题,我建议采用另一种方法。由于两个数组都包含混合大小写的单词,因此将其中一个数组转换为正则表达式,并使用不区分大小写的标志对另一个数组中的所有单词测试每个正则表达式。
const单词= ['word1','WORD2','Word3'] const文本= [{ :'blah',描述:'Word4'},{名称:'blah2',描述:'Word1'},{name:'blah3',描述:'Word5'}] console.log(texts.some(({ description})=> {const regexp = new RegExp(description,'i')返回words.some(word => regexp.test(word))}))
如果您的单词也包含非字母数字字符,我高度建议您借用此功能以逃避y我们的正则表达式正确。如果不逃避它们,可能会遇到以下情况,导致代码抛出错误或提供错误的结果。
函数escapeRegExp(text){返回text.replace(/ [-[\] {}()* +?。,\\ ^ $ |#\ s] / g,'\\ $&');}常量单词= ['?WORD1','word2','Word3']常量文本= [{名称:'blah',描述:'Word4' },{name:'blah2',description:'?Word1'},{name:'blah3',description:'Word5'}] console.log(texts.some(({{description})=> {const regexp = new RegExp(escapeRegExp(description),'i')返回单词.some(word => regexp.test(word))}))
I know this been answered multiple times but I can't seem to find an answer based on my situation. I have two arrays:
words ['word1', 'word2', 'word3']
texts [
{name: 'blah', description: 'word4'},
{name: 'blah2', description: 'word1'},
{name: 'blah3', description: 'word5'}
]
I am trying to filter the two arrays and return true if there is a match
I have seen several examples of simple arrays of numbers but that does not apply here.
You can iterate texts
using Array.prototype.some()
and check for matches in words
using Array.prototype.includes()
. This is O(nm) time complexity if the length of words
and texts
are n
and m
respectively.
const words = ['word1', 'word2', 'word3']
const texts = [
{name: 'blah', description: 'word4'},
{name: 'blah2', description: 'word1'},
{name: 'blah3', description: 'word5'}
]
console.log(
texts.some(
({ description }) => words.includes(description)
)
)
Another solution that's O(n + m) time complexity uses Set.prototype.has()
instead, but this approach will likely be negligibly faster or even a little slower if words
is a small array, so only use this if words
is extremely large.
const words = new Set(['word1', 'word2', 'word3'])
const texts = [
{name: 'blah', description: 'word4'},
{name: 'blah2', description: 'word1'},
{name: 'blah3', description: 'word5'}
]
console.log(
texts.some(
({ description }) => words.has(description)
)
)
Update
To address your issue regarding case-sensitivity, I recommend a somewhat different approach. Since both arrays will contain words with mixed casing, convert one of the arrays to regular expressions and test each regular expression against all the words in the other array with the case-insensitive flag.
const words = ['word1', 'WORD2', 'Word3']
const texts = [
{name: 'blah', description: 'Word4'},
{name: 'blah2', description: 'Word1'},
{name: 'blah3', description: 'Word5'}
]
console.log(
texts.some(({ description }) => {
const regexp = new RegExp(description, 'i')
return words.some(word => regexp.test(word))
})
)
If your words contain non-alphanumeric characters as well, I highly suggest you borrow this function to escape your regular expressions properly. If you don't escape them, you could potentially end up with cases like below causing your code to throw errors or provide incorrect results.
function escapeRegExp(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
const words = ['?WORD1', 'word2', 'Word3']
const texts = [
{name: 'blah', description: 'Word4'},
{name: 'blah2', description: '?Word1'},
{name: 'blah3', description: 'Word5'}
]
console.log(
texts.some(({ description }) => {
const regexp = new RegExp(escapeRegExp(description), 'i')
return words.some(word => regexp.test(word))
})
)
这篇关于用另一个过滤一个数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!