在Javascript中优化搜索首字母

时间:2012-02-16 11:56:01

标签: javascript search optimization

我需要使用Javascript搜索首字母(不确定这是否是正确的名称,如果不是,有人请改变问题)。例如:

使用主题"mas"搜索"Abraham Maslow"将返回true,在"John"中搜索"Johnathan Smith"也会true。但是,在"gold"上搜索"Marygold Ding"将为false

我最初想到:

function search(initial, subjectsArray) {
    var result = [];
    var tmp = null;
    var initialLowercase = initial.toLowerCase();
    for (var i = 0; i < subjectsArray.length; i++) {
        tmp = subjectsArray[i].toLowerCase();
        if (tmp.startsWith(initialLowercase) 
                || tmp.indexOf(' ' + initialLowercase) != -1) {
            result.push(subjectsArray[i]);
        }
    }
    return result;
}

如何优化此代码?

4 个答案:

答案 0 :(得分:3)

好像你想在不区分大小写的正则表达式中使用“单词边界”匹配,例如:

/\bmas/i.test("Abraham Maslow") === true

/\bJohn/i.test("Johnathan Smith") === true

/\bgold/i.test("Marygold Ding") === false

\b将匹配单词的开头或结尾,而正则表达式末尾的i会使其不区分大小写,以便mas可以匹配Maslow

- 更新:

如果你的字符串包含重音字符,那么\ b将匹配它们,即使我们认为它们是单词的一部分。在这种情况下,您希望使用(^|\s)来匹配“字符串的开头或某些空格”:

/(^|\s)c/i.test('Drácule Smith') === false

/(^|\s)dr/i.test('Drácule Smith') === true

/(^|\s)smi/i.test('Drácule Smith') === true

MDN regex documentation

答案 1 :(得分:2)

为什么不使用RegExp?

string.search(new RegExp('\\b' + word + '\S*', 'i')) !== -1

由@ user24编辑,使用与OP相同的api将其构建为函数:

function search(initial, subjectsArray) {
  // Create regex for initial
  var regex = new RegExp('\\b' + initial + '\S*', 'i');
  // Find subjects which contain this substring
  for (var i = 0; i < subjectsArray.length; i++) {
    if(subjectsArray[i].search(regex) !== -1) {
      return true;
    }
  }

  return false;
}

答案 2 :(得分:1)

不能只是<start of input or whitespace>Token

(/(^|\s)Drá/i).test("Dráculezz Smith")

答案 3 :(得分:0)

正则表达式的另一种选择是你可以单独存储名字的字母,每个级别都有一个'matches'元素,包含与该值匹配的名称(应该非常快,但是如果你有很多名称,数组将是巨大的。)

array
| - m
| - matches
| - - 'Abraham Maslow'
| - - 'John Motson'
| - a
| - - matches
| - - - 'Abraham Maslow'
| - - s
| - - - matches
| - - - 'Abraham Maslow'
| - - - l
| - - - - matches
| - - - - - 'Abraham Maslow'
...
| - s
| - - matches
| - - 'Johnathan Smith'
| - - m
| - - - matches
| - - - - 'Johnathan Smith'
| - - - - i

这应该针对速度进行优化,因为你可以做这样的事情来查找名称:

var initials = initial.split('');
var matches;
for (var x in initials)
{
    matches = initials[x];
}
matches = matches['matches']; // now contains ['Abraham Maslow','John Motson'] or ['Abraham Maslow'], etc

这样,你永远不会去一个除了你感兴趣的东西之外的分支,所以当名字不以“S”开头时你永远不会考虑“Johnathan Smith”,并且从不考虑“ John Motson“当名字以”Ma“而不是”Mo“等开头时