Javascript: Flattening a Multidimensional Array

Written by:
Published on

A friend had asked me about converting a 2-dimensional array into a flat 1-dimensional array. In array form this would be (written as was provided to me):

    in = [1,"2",[3,"4"]];
    out = [1,"2",3,"4"]; //this is what he wanted out.

Keywords

Given this task I started to code. However, I had forgotten one glaring issue. His code would fail from the start. He could never use the variable “in” because “in” is a reserved keyword in Javascript.

http://www.quackit.com/javascript/javascript_reserved_words.cfm

Reserved keywords are those special words that you can’t use as variables because they have some significant meaning to the Javascript interpreter. In this case “in” is used for certain for loops.

Maybe this was a trick question or maybe he just happened to use those variable names. I changed the input variable and tried to figure out the problem.

Type Checking Variables

My friend also wanted to make sure that the variable being passed into the function was an array. As I somewhat knew already, this type checking brings all sorts of issues with Javascript. “typeof” is a keyword that allows you to check what data type a variable is, but it has some limitations for Arrays and is best used in checking if something is undefined. Arrays will output a typeof “Object” instead of “Array”.

I found that “instanceof” would work, however it has issues if two different objects have the same prototypical attributes. A Javascript object with the class name of “Object” is the same as “Other” if both objects have the same attributes. Doing a bit more research led me to this website which describes a better way to check arrays (and the possibly incorrect ways that systems like JQuery used to use). Doug Crockford suggested Duck Typing in 2003 to address the issue of typing objects and John Resig points out that “as of 1.3 jQuery no longer uses instanceof or .constructor – for the same reasons that you list here. We were especially hitting problems when dealing with cross-frame pages.”

The Code

Without further adieu, here’s the code.

//can't use "in" as a variable!
inArr = ["1",[2,["3"]],4,[5,[6,7,8,[9,[10]]]]];

out = flatten(inArr);
debug(out);

/**
 * Flattens a multidimensional array into a flat 1D array.
 * @param arr -  a multidimensional array
 * @param arrOut - Optional, an initial array
 * @return a flat array
 */
function flatten(arr, arrOut){
	if(typeof arrOut === "undefined") //optional variable
		var arrOut = []; //new Array or [] work the same
	
	//not so easy to simply check if it's an array
	//http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
	if(Object.prototype.toString.call(arr) === '[object Array]'){
		//loop through array values
		for(var i = 0; i < arr.length; i++){
			console.log(i+" - "+arr[i]);
			//check if there's a sub-array
			if(Object.prototype.toString.call(arr[i]) === '[object Array]'){
				//recurse!!
				arrOut = flatten(arr[i],arrOut);
			}else{
				//push the value onto the exising array
				arrOut.push(arr[i]);
			}
		}
	}
	return arrOut; //return the modified array
}

//just a helper function to show the array
function debug(obj){
	out = "";
	for(i in obj){
		out += i+" - "+obj[i]+"\n";
	}
	alert(out);
}

This entry was posted in Javascript and tagged , , , , , , , by Allan Bogh. Bookmark the permalink.
Allan Bogh

About Allan Bogh

I'm a lead engineer with Disney ID, developing the next generation login website that business entities will incorporate into their websites.

I'm an Active Directory consultant, programmer, web developer, database developer, and tinkerer. I am also the administrator of The Open Code Project. I created and moderate r/ActiveDirectory and, am the primary developer of Reddit Uppers and Downers Enhanced (a part of RES). I also have a love of robotics, working with the Arduino platform.

Sample Projects:

 

  • Disney Examples to come!
  • ImgAlbum - ImgAlbum is a picture album website that includes speedy image delivery using custom GD2 PHP code and folder/subfolder traversal. Other album websites such as Picasa don't include sub-albums or subfolder uploads, so I am developing my own system where a user can upload an entire folder structure full of images and the system will automatically process the images to create albums.

 

 

  • Reddit Uppers and Downers Enhanced - Lead developer, improved speed significantly, incorporated other developers' additions with attribution, project is a part of RES and is used by tens of thousands of people every day.

 

 

  • RE/Max Properties website - Created MLS replication system, pulling NWMLS XML records using PHP. Created a Google Maps interface to display NWMLS results on the website (no longer in use). Before leaving I created a home value calculator based on the MLS data and make the website into a template system for agents.

 

 

  • Stealth Media Solutions - A website and graphic design company that I used to work for. The website was designed by our designer, I implemented the code with rudimentary means compared to the frameworks available today.

 

 

  • Photography Plus - Another design of Stealth Media Solutions. This website includes a WYSIWYG editor for the owner to modify pages. It uses PHP, and Flash.

 

 

  • Highpointe Church - Flash PoC. Highpointe Church wanted a proof of concept design from Stealth Media Solutions. Our designer made it and I created the webpage in Flash. The customer was very specific about using Flash, although it may not have been the most flexible choice. Custom javascript was developed to resize the background image dynamically (worked best in Firefox and IE).

 




Leave a Reply

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

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>