查找字符串是否包含数组任何值的更快方法

时间:2020-09-29 00:19:32

标签: javascript arrays

我想找到最快的方法(而不是循环数组的每个元素)来查找$string ='hello my name is john'是否包含$array = ['none','tomatos','john']上的任何单词,并且在这种情况下不包含任何单词黑色列出的单词$black_array = ['find','other']

在此示例中,结果应为True。

当前,我循环访问数组的每个元素并使用$string.search($array[i])

5 个答案:

答案 0 :(得分:3)

实现此目的的一种方法是从每个数组中创建正则表达式,并在白名单中测试匹配项,在黑名单中测试匹配项:

const $string = 'hello my name is john';
const $array = ['none', 'tomatos', 'john'];
const $black_array = ['find', 'other']

const white = new RegExp('\\b(' + $array.join('|') + ')\\b');
const black = new RegExp('\\b(' + $black_array.join('|') + ')\\b');

const match = white.test($string) && !black.test($string);

console.log(match);

答案 1 :(得分:2)

听起来像您可以将Array.prototype.some()组合为允许的单词,将否定的Array.prototype.every()组合为禁止的单词。

const wordToRegex = word => new RegExp(`\\b${word}\\b`, "i")

const check = (str, allowed = [], banned = []) =>
  allowed.some(word => wordToRegex(word).test(str))
    && banned.every(word => !wordToRegex(word).test(str))
  
const allowed = ['none','tomatos','john']
const banned = ['find','other']

console.info(check('hello my name is john', allowed, banned))
console.info(check('hello my other name is john', allowed, banned))

不确定我是否称其为 fast 。最好使用实际的索引搜索引擎。

答案 2 :(得分:1)

对于较小的阵列大小,其他响应也足够。但是,如果要针对这种情况进行优化,例如,如果数组中有数百万个候选子字符串(通常是优化的动力),则建议构造一个“字符串树”。

在此树中,根分支到每个候选的第一个字节。因此,例如,如果数组仅包含{"none", "tomatoes", "john"},则从根开始将有三个子节点:'n', 't', and 'j'。 (从第一个字节开始的多个候选字符串将通过相同的树节点下降。)然后,这些节点依次分支到候选的第二个字节。依此类推。

这种方法允许您对字符串中的每个字节进行少量比较:始终小于255,但通常要少得多。相比之下,如果您有一百万个候选字符串,则使用其他建议的方法(包括公认的方法),在最坏的情况下(这也是我们通常针对之优化的情况),您将必须对每个字符串字节进行数百万次比较

答案 3 :(得分:0)

您可以使用Array.join()RegExp()。例如:

let $string ='hello my name is john';
let $black_string ='hello my name is other';
let $black_string2 ='hello my name is mother';
let $array = ['none','tomatos','john'];
let $black_array = ['find','other'];

let re = new RegExp("\\b"+$array.join("\\b|\\b")+"\\b");
let re_blck = new RegExp("\\b"+$black_array.join("\\b|\\b")+"\\b");
let $hasArray = re.test($string);
let $hasBlackArray = re_blck.test($string);
console.log($hasArray,$hasBlackArray);
$hasArray = re.test($black_string);
$hasBlackArray = re_blck.test($black_string);
console.log($hasArray,$hasBlackArray);
$hasArray = re.test($black_string2);
$hasBlackArray = re_blck.test($black_string2);
console.log($hasArray,$hasBlackArray);

答案 4 :(得分:0)

您可以使用多个条件检查来实现

const array = ["none", "tomatos", "john"]
const black_array = ["find", "other"]
const check = (str) =>
  [
    array.some((word) => str.includes(word)),
    black_array.every((word) => !str.includes(word)),
  ].every((criteria) => criteria === true)

console.log(check("hello my name is john"))
console.log(check("hello my name is other"))
console.log(check("hello my name is peter"))

相关问题