The extended map function
The map function I will present is the most useful map function you'll find. Why? Because it can replace most for loops! And replacing for loops will produce much cleaner JavaScript code.
What is a map function? Standard map function applies a function to a sequence of elements. Let's do a rewrite that will show you what I mean. A for loop could like this: var list = [1, 2, 3]
for(var i=0; i < list.length; i++)
myFn(list[i])
Rewritten using map the above loop will look like this: map([1, 2, 3], my_fn)
Much cleaner don't you think? The extensionsMost library's (JQuery, Prototype, MochiKit) implement a dumb map function, that acts as "the real map function", i.e. a map function that can only apply a function to a sequence of elements and nothing more. But I figured out there is no need to put such a limitation. The map function could be almost as powerful as a for loop! My map function signature looks like this: map(list, fn, /*optional*/ start_index, end_index)
Notice that you can specify a start_index and end_index, an example: map(['A', 'm', 'i', 'r'], function(char) {
alert(char)
}, 1, 3)
The above code will alert 'm', 'i'. The above example looks like this using a standard for loop: var chars = ['A', 'm', 'i', 'r'];
for(var i=1; i < 3; i++) {
alert(chars[i])
}
That's the first extension and you may find it quite useful in certain situations. The second extension is, that you can get the current index, an example: map(['A', 'm', 'i', 'r'], function(char, i) {
alert(i + ':' + char);
});
The above example will alert 0:A, 1:m, 2:i, 3:r. This extension is also quite useful in certain situations. The third extension is, that you can return from a map function - this is really useful. An example: var is_i_found = map(['A', 'm', 'i', 'r'], function(char) {
if(char == i)
return true;
});
alert(is_i_found); //Alerts true
Anyway, the extensions may look like an overkill, but I can assure you that they are quite useful. In Todoist I only use around 6 for loops (and I have around 5000 lines of JavaScript), everything is handled by the extended map function! The implementationfunction map(list, fn,/*optional*/ start_index, end_index) {
var i = 0, l = list.length;
if(start_index)
i = start_index;
if(end_index)
l = end_index;
for(i; i < l; i++) {
var val = fn.apply(null, [list[i], i]);
if(val != undefined)
return val;
}
}
That's it. You'll find this map function in AJS (my JavaScript library). A real world exampleIn Todoist it's possible to write a every last day recurring event. In order to implement this, one needs to know the last day of a month. Here is how I solve this using the extended map function: function getLastDay(_date) {
var clone = new Date(_date);
var now_month = _date.getMonth();
return map([31, 30, 29, 28], function(days) {
now = new Date(clone);
now.setDate(days);
if(now_month == now.getMonth())
return now;
});
}
The above code takes a date as input and returns a new "last day" date object. Notice the usage of map.
Code
·
JavaScript
·
Tips
•
26. Apr 2007
7 comments so far
Post a comment
Commenting on this post has expired.
|
Blog labels |