Created
March 14, 2013 04:51
-
-
Save th507/5158907 to your computer and use it in GitHub Desktop.
recursively flatten array in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * @name arrayEqual | |
| * @description check if two arrays are equal | |
| * @param {arr} Array to check | |
| * @param {arr} Array to check | |
| * @return {Boolean} Boolean, returns true if arrays are the same | |
| */ | |
| function arrayEqual(a, b) { | |
| var i = Math.max(a.length, b.length, 1); | |
| while(i-- >= 0 && a[i] === b[i]); | |
| return (i === -2); | |
| } | |
| /* | |
| * @name flattenArray | |
| * @description flattens multi-dimension array into one-dimension array | |
| * useful for manipulating function arguments like flattenArray(arguments) | |
| * @usage flattenArray(arr) | |
| * eg. | |
| * [1, 2] => [1, 2] | |
| * [1, [[[[[[2]]]]]]] => [1, 2] | |
| * [1,[2,3],[[[[4]]],5]] => [1, 2, 3, 4, 5] | |
| * | |
| * @param {arr} Array to flatten | |
| * @return {Array} Array, one-dimension array | |
| */ | |
| function flattenArray(arr) { | |
| var r = []; | |
| while (!arrayEqual(r, arr)) { | |
| r = arr; | |
| arr = [].concat.apply([], arr); | |
| } | |
| return arr; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The arrayEqual() approach is certainly unusual, but it's 100% legitimate (it actually fails in two cases, see below).
The
ivariable is declared asMath.max(a.length, b.length, 1), therefore it will be 1 when the function is given two empty arrays, else it'll be the length of the longest array amongaandb.This means that the
whileloop will always:Since the cycle breaks as soon as the two arrays are different, the case where the two arrays are of different length is accounted, except when either
aorbcontains theundefinedvalue, in which case the condition check may fail:Another case where this check fails is when comparing the
NaNvalue:but this is due to the sicked nature of
NaNof not being equal to itself rather than this specific algorithm.Discarded these two special cases, which are probably not an issue for the use of the function in
flatten, we may consider the limit case, i.e. when both arrays are of length 1. In fact, ifi == 1, thewhileloop will become something like this:The function
arrayEqualmay be improved to take the 1st special case into account by extending it a bit:as for the second case, I don't see an elegant way to do it; maybe using
isNaN.As regards the
[].concat.apply([], arr), it's a pretty standard way to "1-level flatten" an array;[].concatis the same as Array.prototype.concat, while concat.apply just appliesconcatusing asthisargument to itself the first argument passed to it (in this case,[], which is used as the base array for the concatenation).