Just another Indie Games Guild weblog

Gazing into the Bucket

I often wonder if Dr. Frankenstein would’ve said … “A strange thing happened while in the lab the other day …”

Well, in this case, I didn’t exactly make a monster from body parts, but I did find myself tried of writing and rewriting loops to determine what exactly is and is not in a JavaScript ‘Array’ structure.

Some backstory … Igor! Activate the Wayback Machine!

I was working on manipulating a database who’s readable data output is a JSON (JavaScript Object Notation for the curious of mind) structure. During a load, some additional flags are calculated and added, usually for use later. Without boring anyone with the details, that would be booleans, timestamps and so on. Basically items I’ll search for later using JSON Query strings.

Now, back to the Present!

Like most, I use Array structures as ad-hoc, temporary storage containers . More often than not, I’m needing to find out, just what the heck I put in there?

So I decided to write a little extension. Now, before I get a gazillion comments… yes I know most frameworks (jQuery, Dojo, etc) have something like this already, but sometimes, if you’re flying without a JS framework, it never hurts to have your own bag of tricks to draw on. Though, I will say, many restrict themselves to a string or numerical based array.

So, in approaching this, I knew I’d have to support the standard “is my raw value in the array?” That’s actually fairly straightforward:

Array.prototype.contains = function(obj) {
var cntr = this.length;
while (cntr–) {
if (this[cntr] === obj) {
return true;
}
}
return false;
}

So, given an array like so:

var _testArray = ["1",2, { "3":"thr ee" }];

The following will pass muster:

(_testArray.contains(“1″) === true )

or

(_testArray.contains(2) === true )

But this will not:

( _testArray.contains( {“3″:”three”} ) === true )

Why? Because our test uses strict equality.  When two objects are tested for strict equality, in JavaScript they must be completely identical. In this case, having {“3″:”three”} within an Array is not completely identical to the object of {“3″:”three”} being passed in for comparison.

Have a headache yet? Don’t worry, JavaScript does that to people.

But, we want to be able to check for objects too, because our array could have an object appear in it at any time! So we make a few adjustments to our original function so it becomes this:

Array.prototype.contains = function(obj) {
var cntr = this.length;
while (cntr–) {
switch ( typeof (obj)) {
case “object”:
for ( var _param in (obj) ) {
if ( ! (this[cntr])[ _param ] ) {
return false;
} else {
if ( (this[cntr])[ _param ] !== (obj)[ _param ] ) {
return false;
}
}
}
return true;
break;
default:
if (this[cntr] === obj) { return true; }
break;
}
}
return false;
}

Now here, we check for the inbound type. If an object, we compare and contrast the contents of inbound object to object stored in array. For a simple cases, like so:

if ( _testArray.contains(“1″) ) { /* do something */ }
if ( _testArray.contains(2) ) { /* do something */  }
if ( _testArray.contains( { “3″: “three” } ) ) { /* do something */ }

or even:

var _testSubj = {“3″:”three”};
if ( _testArray.contains(_testSubj) ) { /* do something */ }

this will get us by quite fine.

As a final thought, the above is by no means as far as one could take this. For instance, there is no check to determine if the objects contain the same number of parameters, or any condition to handle objects within objects that are within arrays, like so:

var _testArray = [ "1", 2, { "3": "three", {"4": "four"} } ];

But hey, I shouldn’t have all the fun, its your turn!

July 27th, 2010 at 11:16 am tagged , , , , ,




Leave a Reply