2012-02-16 12 views
4

イニシャルを検索する必要があります(Javascriptを使ってイニシャルを検索する必要があります。たとえば:Javascriptでイニシャルの検索を最適化する

対象"Abraham Maslow"を使用して"mas"の検索がtrueを返し、"Johnathan Smith""John"を探しうもtrueだろう。ただし、"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

したがって、基本的に名前(または名前のリスト)があり、特定の部分文字列が姓または名の先頭かどうかを確認したいのですか?イニシャルは正しい言葉ではありませんが、私は良い言葉を考えることもできません。あなたはフォーマットに関して何を保証できますか? –

+0

略語? :) – Joe

+0

@AnthonyGrist主題のフォーマット?それらは1つ以上のスペースを含む文字列のリストです...例えば、名前の1つは 'Karlson'であり、他のものは' John Ronald Reuel Tolkien'です。 – RedDragon

答えて

3

あなたは、たとえば、大文字と小文字を区別しない正規表現にマッチする「単語の境界」を使いたいように思えます。

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

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

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

\bは、単語の先頭や末尾にマッチし、正規表現の末尾にimasMaslowに一致することができるように、それは大文字と小文字を区別しないことができます。

- 更新:あなたの文字列がアクセント文字が含まれている場合

、\ bは、我々は彼らが単語の一部であると考えていても、それらにマッチします。

/(^|\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:その場合は、あなたは、 "文字列の先頭またはいくつかの空白" を一致させるために、代わりに(^|\s)を使用します。

+1

これは '(/\bc/i).test("DráculeSmith") ':-(( – RedDragon

+0

)では機能しません。"単語境界 "はaz、AZ、0-9だけを単語とみなす-ccharacters。私の答えを更新します –

2

代わりにRegExpを使用しないのはなぜですか? OPと同じAPIで関数にこれを構築するために、@ user24によって

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

編集:

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

0

regexの代わりに、各レベルに '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 

これはかなりよく、速度を最適化する必要があります。

​​

この方法は、あなたが他の何かを持っているブランチを下ることはありません名前が「S」で始まらないときは「Johnathan Smith」とは決して考えず、「Mo」ではなく「Ma」で始まる名前を「John Motson」とは決して考慮しません。など

1

ただあなたをカンターする<start of input or whitespace>Token

(/(^|\s)Drá/i).test("Dráculezz Smith") 
関連する問題