ruby-like syntax for javascript array functions

At work, we recently decided to use YUI (Yahoo UI) to generate our user interface. YUI is great. It got almost all the widgets we need. Tabs, tree, carousel... As a result, we have consistent look all throughout. We dump the javascript framework that came with Ruby on Rails and use YUI instead.

Now, here's the problem. If you've use prototype or jQuery, you must be used to using the utility functions these frameworks provide. I go big on jQuery's each function for iterating through arrays and array-like object. Unfortunately, YUI - in version 2.x, at least - does not provide these array functions.

In a course of an hour, I wrote a handy set of functions to get me through. It could've been easier if I just include jQuery since the noConflict function makes it work with any js framework but then I got a mandate to focus on YUI.

JavaScript:
  1. Array.each = function(a, fn){
  2.     for(var i=0; i <a.length; i++){
  3.         fn(a[i]);
  4.     }
  5. };
  6.  
  7. Array.prototype.each = function(fn){
  8.     Array.each(this,fn);
  9. };
  10.  
  11. Array.collect = function(a, fn){
  12.     var new_array = new Array();
  13.     a.each(function(e){
  14.         new_array.push(fn(e));
  15.     });
  16.     return new_array;
  17. };
  18.  
  19. Array.prototype.collect = function(fn){
  20.     return Array.collect(this, fn);
  21. };
  22.  
  23. Array.inject = function(a, init, fn){
  24.     a.each(function(e){
  25.         init = fn(init, e)
  26.     });
  27.     return init;
  28. };
  29.  
  30. Array.prototype.inject = function(init, fn){
  31.     return Array.inject(this, init, fn);
  32. };
  33.  
  34. Array.detect = function(a, fn){
  35.     for(var i=0; i <a.length; i++){
  36.         if(fn(a[i])){
  37.             return a[i];
  38.         }
  39.     }
  40. };
  41.  
  42. Array.prototype.detect = function(fn){
  43.     return Array.detect(this, fn);
  44. };
  45.  
  46. Array.select = function(a, fn){
  47.     var new_array = new Array();
  48.     a.each(function(e){
  49.         if(fn(e)){
  50.             new_array.push(e);
  51.         }
  52.     });
  53.     return new_array;
  54. };
  55.  
  56. Array.prototype.select = function(fn){
  57.     return Array.select(this, fn);
  58. };
  59.  
  60. Array.reject = function(a, fn){
  61.     return a.select(function(e){
  62.         return (!fn(e));   
  63.     });
  64. };
  65.  
  66. Array.prototype.reject = function(fn){
  67.     return Array.reject(this,fn);
  68. };
  69.  
  70. Array.reduce = Array.inject;
  71. Array.prototype.reduce = Array.prototype.inject;
  72. Array.map = Array.collect;
  73. Array.prototype.map = Array.prototype.collect;

Use it like:

JavaScript:
  1. >>> var a = [1,2,3,4];
  2. >>> a.reduce(0, function(x,y){ return (x+y); });
  3. >>> 10

Basically, almost all functions are built on top of Array.each so I'm not sure how fast it'll go.

Happy hacking.

Leave a Reply