I have an array that looks like this (but can be very big, and with longer strings):
var treeOfStrings = [
'abc',
'def',
[
'ghij',
[
'k',
'l'
],
'mnop'
],
'qrst',
'uv',
'wxyz'
];
I want to turn it into a single string, but since it is big and this is in a performance sensitive place, I'd like to do it in a very efficient way.
The current approach (below) is to first make a single array (by recursively walking the children and using push() on a single output array), and then doing a join()....but it seems like there could be a more efficient way, since this one is pretty heavy on the usage of push() so it could do lots of little allocations.
function treeJoin(tree) {
var out = [];
flattenArray(tree);
return out.join('');
function flattenArray(branch) {
var len = branch.length;
var item;
for(var i=0; i<len; i++) {
item = branch[i];
if(typeof item === "string")
out.push(item);
else
flattenArray(item);
}
}
}
(the solution will need to work in all reasonably modern browsers as well as node.js)
Edit:
I timed these functions, and interestingly, the simplest way of doing it (well, simplest to me) is actually the fastest (see below). I would have thought doing "+=" on a string over and over was slow, but nope, it's screaming fast (in Chrome). Over ten times faster than the method below that uses map() and join(), and about 6 times faster than the method that overrides Array.toString(), and twice as fast as my method that flattens the tree into a single array and then uses a single join(). Crazy.
treeJoin = function (tree) {
var s = ''
var len = tree.length;
var item;
for(var i=0; i<len; i++) {
item = tree[i];
if(item.push)
s += treeJoin(item);
else
s += item;
}
return s
}