Friday, July 22, 2011

JQuery Utility Functions - grep()

JQuery's documentation can be a little light sometimes. Today we're looking at an underused core JQuery  function: $.grep()

First, the weird name. If you're not a Linux nerd, you should know that grep is a command in Linux that essentially searches, or more specifically, filters, stuff you pass to it. I would've preferred they call this command .filter() or .where(), but so be it.

As you've likely inferred, grep filters an array or collection of tags. It's like the WHERE clause from SQL or .Where(x => x...) in .NET's LINQ.

I'm going to send you straight to the fiddle for the code:

$.grep() example over an array

And of course, you can use it over a collection of tags - but the syntax is strange. For example, if you want to get a collection of input tags on the page where the user typed at least 10 characters:

var inputs = $.grep($('input[type=text]'), function(input) {
    return input.value.length > 9;
});

What's odd about this is it breaks convention with the rest of the JQuery collection methods. For example, you can set the text color to red for all tags selected with:

$('div').css('color', 'red');

So you would expect this to work:

$('div').grep(...

But it does not, even in the most recent version (as of this posting, 1.6.2). Instead you have to use .filter().

So now with the previous blog post on $.map(), we can get a little fancy. Suppose we've got a bunch of address objects from the server of the format:

var addresses = [
  {
    name: 'Brass Nine Design',
    address1: '321 Sesame St',
    city: 'Sesame',
    state: 'MA'
  }, ...
];

Suppose the user is going to enter a string, and you need to search names and addresses against it, then show the user the companies that match - listed by name. Remember that map is essentially SQL's select, and grep is essentially SQL's where. First you filter the list with grep, then extract the fields you wanted with map:

var matchingNames = $.map($.grep(addresses, function(addr) {
  return addr.name.indexOf(phrase) >= 0 || addr.address1.indexOf(phrase) >= 0;
}), function(addr) {
  return addr.name;
});

Voila.

No comments:

Post a Comment