Created
March 22, 2011 06:39
-
-
Save ded/880861 to your computer and use it in GitHub Desktop.
use this as input
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<a href="http://en.wikipedia.org/wiki/Autocomplete">Autocomplete widgets</a> live in nearly all systems that requires filtering items via input against large amounts of data. This includes address books, email contacts, restaurants, even social graphs. | |
However, in most matching algorithms, Engineers don't take into account that people don't know how to spell AND/OR are lazy. Thus here is a <em>really simple</em> solution to work around this problem, and in my own opinion, will vastly improve the user experience. | |
<h3>Look ahead matching</h3> | |
Let's say you have five people. Daniel, Dustin, David, Damarcus, and Russ. Now let's say a user types in <em>dus</em>. We would match <b>Dus</b>tin and <b>D</b>amarc<b>us</b>. Likewise, if we typed in <em>us</em>, we would get an output of D<b>us</b>tin, Damarc<b>us</b>, and R<b>us</b>s. | |
<h3>Enter RegExp</h3> | |
At this point, it's sort of a no-brainer. Your input-based regular expression can be created as such: | |
<pre><code>var people = ['Daniel', 'Dustin', 'David', 'Damarcus', 'Russ']; | |
function matchPeople(input) { | |
var reg = new RegExp(<b>input.split('').join('\\w*').replace(/\W/, "")</b>, 'i'); | |
return people.filter(function(person) { | |
if (person.match(reg)) { | |
return person; | |
} | |
}); | |
}</code></pre> | |
Voila! Now you never have to type another vowel again! (At least in spirit... you know what I mean). In addition to this, you can do further post-process sorting based on <a href="http://en.wikipedia.org/wiki/Levenshtein_distance">Levenshtein distance</a> which will graduate better matches to the top. | |
<h3>An Aside: Caching</h3> | |
Since this tends to do be heavy on regular expression construction, a good idea would be to cache your compiled expressions. This can easily be done using my <a href="http://www.dustindiaz.com/javascript-cache-provider/">Cache Provider</a> as such: | |
<pre><code>var regCache = new CacheProvider; | |
function matchPeople(input) { | |
var reg = regCache.<b>get</b>(input) || regCache.<b>set</b>(input, new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i')); | |
// etc... | |
}</code></pre> | |
Now any subsequent calls to the same input will run against a pre-compiled expression. And that folks, is all I got for the night. Cheers. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment