The idea of using regex and \b is fine, but it's better to abstract things out into functions where possible. In this case, it's possible to write a completely general function that takes a function telling it whether to keep an item. The usual name for this function is 'filter', and it's very useful in all sorts of situations — so useful, in fact, that it's built-in as of Javascript 1.6. Unfortunately, IE doesn't support this yet, so we have to roll our own anyway.
Code:
// Our filter function.
// We've put it on Array, for neatness.
Array.filter = function(f, a) {
// Iterate over our 'array' a (it needn't really be an array, so
// this will work on NodeLists and the like too). r is the new
// array we'll be returning.
for (var i = 0, n = a.length, r = []; i < n; ++i)
// We pass the key as the second argument, as well. If the
// function we pass to filter() doesn't care about this, it can
// ignore it.
if (f(a[i], i))
// Add the current element onto the end of r.
r[r.length] = a[i];
return r;
};
// map() is a function in a similar vein, but rather than deciding
// whether to keep elements, it simply applies a function to each
// one, transforming them. Also built-in as of JS1.5.
Array.map = function(f, a) {
for (var i = 0, n = a.length, r = []; i < n; ++i)
r[i] = f(a[i], i);
return r;
};
var shoearray = ["blue shoes",
"new blue shoes",
"orange shoes",
"new orange shoes",
"red shoes",
"green shoes new"];
// Here's our predicate function to decide whether to keep an item.
function shoesAreNew(shoestring) {
return /\bnew\b/.test(shoestring);
}
// Here we use map() only for the side effect caused by alert().
Array.map(alert, Array.filter(shoesAreNew, shoearray));
I opted to put these functions on Array and pass the collection to which they apply explicitly, rather than put them on prototype. This is for two reasons: firstly, it means I don't have to check whether I'm clobbering the built-in ones
, and secondly, it allows me to pass a non-array collection such as a NodeList directly, rather than doing Array.prototype.filter.call(myNodeList, myPredicate) as the Mozilla implementation requires. The Mozilla implementation is situated on the prototype, however, so to write it using those would look like this (note that forEach() differs from map() only in that it ignores the return values):
Code:
var shoeArray = ["blue shoes",
"new blue shoes",
"orange shoes",
"new orange shoes",
"red shoes",
"green shoes new"];
function shoesAreNew(shoestring) {
return /\bnew\b/.test(shoestring);
}
shoearray.filter(shoesAreNew).forEach(alert);
vwphillips: until IE has decent support for XHTML, you probably shouldn't recommend it to people — certainly not without a note about sending the proper Content-Type. Transitional DOCTYPEs are meant for the transition from HTML3 to HTML4, and shouldn't be used on new pages.
Bookmarks