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
i
variable 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 amonga
andb
.This means that the
while
loop 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
a
orb
contains theundefined
value, in which case the condition check may fail:Another case where this check fails is when comparing the
NaN
value:but this is due to the sicked nature of
NaN
of 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
, thewhile
loop will become something like this:The function
arrayEqual
may 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;[].concat
is the same as Array.prototype.concat, while concat.apply just appliesconcat
using asthis
argument to itself the first argument passed to it (in this case,[]
, which is used as the base array for the concatenation).