2012-02-16 39 views
4

我需要使用Javascript來搜索首字母(不確定這是不是正確的名稱,如果不是,請改變問題)。例如:使用主題"Abraham Maslow"將返回true,並搜索"John""Johnathan Smith"也將是true在JavaScript中優化縮寫搜索

搜索"mas"。但是,在"Marygold Ding"上搜索"gold"將是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

所以,基本上,你有一個名字(或名稱列表),你想檢查某個子字符串是否是名字或姓氏的開始?首字母縮寫不是正確的詞,但我也想不出一個更好的詞。你可以對格式做出什麼保證? – 2012-02-16 11:58:57

+0

縮略語? :) – Joe 2012-02-16 11:59:53

+0

@AnthonyGrist主題的格式?它們將是任何包含一個或多個空格的字符串列表......例如,其中一個名稱將只是「卡爾森」,而另一個名稱則是「John Ronald Reuel Tolkien」。 – RedDragon 2012-02-16 12:01:25

回答

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

這不適用於'(/\bc/i).test("DráculeSmith「)':-( – RedDragon 2012-02-16 12:25:40

+0

因爲」單詞邊界「只考慮az,AZ,0-9是單詞 - 字符,我會更新我的答案 – 2012-02-16 12:27:45

2

爲什麼不使用RegExp呢?

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

編輯通過@ user24建立與相同的API OP功能是:

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; 
} 
+1

這在以下情況下不起作用:''DráculeSmith'.search(new RegExp('\\ b'+'c'+'\ S *','i'))!== -1)' :-( – RedDragon 2012-02-16 12:16:54

0

正則表達式的替代方法是,您可以單獨存儲名稱的字母,並在每個級別都包含匹配該值的「匹配」元素(應該相當快,但如果您有大量的的名字,陣列將是巨大的)。

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 

這應該速度相當不錯的優化,因爲你可以做這樣的事情來查找一個名字:

​​

這樣,你永遠不會下降,這具有其他任何一個分支而不是你感興趣的,所以當名字不是以「S」開頭的時候你永遠不會考慮「Johnathan Smith」,並且當名字以「Ma」開頭而不是「Mo」時,永遠不會考慮「John Motson」等

1

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

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