Array Tidy

I’ve been working on a selector engine recently, and given the complexity of it, it’s easier to return a multi-dimensional array than a flat one (for example: [['this'], 'is', ['an', 'example']] instead of ['this', 'is', 'an', 'example']). Of course, returning such an array to another function is a bit pointless because it requires that function to traverse through the array in order to flatten it so it can be used efficiently. Another problem with the selector engine is that sometimes, an element can be returned twice (for example: $('div, #content'), where #content is a div). Because of this, I wrote a tidy function that flattens the array and removes duplicate indexes.

Unfortunately, it requires some additional code:

indexOf

Returns the first index where a value (searchStr) appears. startIndex allows you to begin the search at a predefined index.

Array.prototype.indexOf = Array.prototype.indexOf || function(searchStr, startIndex) {
	for(var i = startIndex || 0, thisLength = this.length; i < thisLength; i++) {
		if(searchStr === this[i]) {
			return i;
		}
	}

	return -1;
};

inArray

Returns either true or false if a value (searchStr) is in an array. startIndex allows you to begin the search at a predefined index.

Array.prototype.inArray = function(searchStr, startIndex) {
	return this.indexOf(searchStr, startIndex) > -1;
};

flatten

Flattens a multi-dimensional array to a one-dimensional array.

Array.prototype.flatten = function() {
	for(var i = 0, thisLength = this.length, b = []; i < thisLength; i++) {
		if(this[i].constructor === Array) {
			this[i] = this[i].flatten();

			for(var j = 0, thisILength = this[i].length; j < thisILength; j++) {
				b.push(this[i][j].constructor === Array ? this[i][j].flatten() : this[i][j]);
			}
		}
		else {
			b.push(this[i]);
		}
	}

	return b;
};

tidy

Tidies up an array by removing dupe values and flattening it to a one dimensional array.

Array.prototype.tidy = function() {
	var a = this.flatten();
	var b = [];

	for(var i = 0, aLength = a.length; i < aLength; i++) {
		if(!b.inArray(a[i])) {
			b.push(a[i]);
		}
	}

	return b;
};

All this code has been tested on the following browsers and works perfectly:

  • Firefox 1.5, 2, 3, 3.5
  • Chrome 1, 2, 3
  • Opera 7, 8, 9.5, 9.64, 10
  • Safari 3, 4
  • Internet Explorer 6, 7, 8

Comments

No responses have been made so far. Add your comments.

    What do you think? Leave a comment...