Skip to content

Instantly share code, notes, and snippets.

@ded
Created March 22, 2011 06:39
Show Gist options
  • Save ded/880861 to your computer and use it in GitHub Desktop.
Save ded/880861 to your computer and use it in GitHub Desktop.
use this as input
<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