Monday, December 22, 2008

The join() case for a better select()

Today's bug in JavaScript code: was using the Array's join() function and getting results which did not match the expectations. Turns out, that in a case of sparse array (with missing data at certain indexes) join inserts an empty string. So, considering the code:

var a = ['zero', 'one', 'two'];
a[4] = 'four';
alert(a.join(':'));

The resulting alert will be «zero:one:two::four».

Duh! To adjust to the behavior I have modified the Ruby-like selector to have the «pack» parameter like in this:

// pack   is truthy: (default) resets indexes, returns new packed array
// pack   is falsy:  preserves indexes, returns new sparse array
// tester is a filtering function. Should accept the array's
//        element and return truthy or falsy.
Array.prototype['select'] = function(pack, tester){
  if (typeof(pack) == 'function') {
    tester = pack;
    pack = true;
  } else if (typeof(tester) != 'function'){
    throw { name: 'ArgumentError', message: 'Function expected. Should accept the array\'s element and return truthy or falsy.' }
  };
  result = [];
  for (i in this) {
    if ( tester(this[i]) ) {
      if (pack) { result.push(this[i]); }
      else      { result[i] = this[i]; };
    };
  };
  return result;
};

Here are the Firebug runs of the select(...):

>>> [ 1, 2, 3, 4, 5, 6].select( function(e){ return e>3; } )
4,5,6
>>> [ 1, 2, 3, 4, 5, 6].select( false, function(e){ return e>3; } )
,,,4,5,6
>>> [ 1, 2, 3, 4, 5, 6].select( true, function(e){ return e>3; } )
4,5,6

Let me know, if this does not work in IE or others for whatever reason - I have only tested it in Firefox.

read more ...

No comments :

Post a Comment

Comments which in my opinion do not contribute to a discussion will be removed.