Useful JavaScript Game Extensions: Array#remove

Debris Removal
Part 4: Array#remove

JavaScript Arrays are missing some very common, very useful functions. One of those is the remove method. We want to be able to say “Hey you, array, remove this object from yourself! Now!!” But our poor JS array’s don’t know how. They can barely remove elements from specific indices, let alone a specified object. Well no longer! Now they’ll do what we say.

/**
 * Remove the first occurance of the given object from the array if it is
 * present.
 *
 * @param {Object} object The object to remove from the array if present.
 * @returns The removed object if present otherwise undefined.
 */
Array.prototype.remove = function(object) {
  var index = this.indexOf(object);
  if(index >= 0) {
    return this.splice(index, 1)[0];
  } else {
    return undefined;
  }
};

By building off of the Array‘s built in methods we can keep this code very short. We find the first occurrence of the specified object using indexOf, then we remove and return it using splice. If it wasn’t found we return undefined instead.

// An illustrative test suite
 
test("Array#remove", function() {
  ok([1,2,3].remove(2) === 2, "[1,2,3].remove(2) === 2");
  ok([1,3].remove(2) === undefined, "[1,3].remove(2) === undefined");
  ok([1,3].remove(3) === 3, "[1,3].remove(3) === 3");
 
  var array = [1,2,3];
  array.remove(2);
  ok(array.length === 2, "array = [1,2,3]; array.remove(2); array.length === 2");
  array.remove(3);
  ok(array.length === 1, "array = [1,3]; array.remove(3); array.length === 1");
});

John Resig has another take on Array#remove, remove by index. You may want to take a look at that as well, though for me it feels more natural to remove by specified object rather than by specified index.

2 thoughts on “Useful JavaScript Game Extensions: Array#remove

  1. Nice, it looks like there is a lot of useful stuff in there! My main issue is that using things like $.map(array, iterator) or _.map(array, iterator) still add an extra symbol that needs to be parsed mentally. It’s more natural for me if each object takes care of it’s own methods such as array.map(iterator). There are merits to both techniques though. Not messing with the global or built in name spaces can be very important if your code needs to run in diverse environments across the widest range of platforms and conditions. I definitely appreciate that library code like jQuery and Underscore.js don’t want to generate conflicts with anyone’s namespace, but for my own applications I’d like to fill in my namespaces with the “best possible” methods so that there are the fewest inconveniences. Of course “best possible” means different things to different people and the diversity and exploration of various techniques is important to determining what will hopefully one day end up in the JavaScript language itself.

Leave a Reply

Your email address will not be published. Required fields are marked *