我需要使用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;
}
如何优化此代码?
答案 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
答案 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“等开头时