I want to define a function .flatten that flattens several elements into one single array. I know that the following is not possible, but essentially I would like to do this:
var flatten = function() {
var flattened = arguments.reduce(function(acc, elem) { return acc.concat(elem) }, []);
return flattened;
};
var arr = [[1,2,3], 4, 5, [6, 7]];
console.log(flatten(arr)) // => [1,2,3,4,5,6,7]
I want to define a function .flatten that flattens several elements into one single array. I know that the following is not possible, but essentially I would like to do this:
var flatten = function() {
var flattened = arguments.reduce(function(acc, elem) { return acc.concat(elem) }, []);
return flattened;
};
var arr = [[1,2,3], 4, 5, [6, 7]];
console.log(flatten(arr)) // => [1,2,3,4,5,6,7]
I get the following error:
TypeError: arguments.reduce is not a function
I understand that the above error is because arguments is only array-like, so it does not have the full capabilities of a true array. So there is the following, but I'm wondering if there is something even cleaner:
var flatten = function() {
var flattened = [].reduce.call(arguments, function(acc, elem) { return acc.concat(elem) });
return flattened;
};
Any good way to rewrite .flatten using .reduce()?
NOTE: I know there are many other ways that you can flatten arrays in javascript, but what I was wondering about here is how to do so with specifically arguments.
Share Improve this question edited Dec 17, 2024 at 16:09 trincot 351k36 gold badges271 silver badges322 bronze badges asked Jul 23, 2016 at 18:20 Aljosha NovakovicAljosha Novakovic 3504 silver badges18 bronze badges 5-
reduce
is not good for flattening arrays. Also, your code works. – castletheperson Commented Jul 23, 2016 at 18:41 -
When you used
.call()
you forgot to pass an empty array as the second argument to.reduce()
. – nnnnnn Commented Jul 23, 2016 at 18:44 - Possible duplicate of Merge/flatten an array of arrays in JavaScript? – castletheperson Commented Jul 23, 2016 at 19:00
- @4castle It is slightly different from that previous question, and these answers were still very helpful for me because my primary confusion was with how to specifically flatten arguments so that in the future I can use the same format (whether .reduce or any other function that operates on an array) – Aljosha Novakovic Commented Jul 23, 2016 at 19:09
-
@AljoshaNovakovic It's just that all of the answers to that question can also be used with
arguments
. All you have to do is useArray.prototype
with whatever, and thencall
usingarguments
. – castletheperson Commented Jul 23, 2016 at 19:11
5 Answers
Reset to default 11Convert the arguments
object to an array first:
var flatten = function() {
var args = Array.prototype.slice.call(arguments);
var flattened = args.reduce(function(acc, elem) { return acc.concat(elem) }, []);
return flattened;
};
Or, use array methods on the arguments
object directly:
var flatten = function() {
var flattened = Array.prototype.reduce.call(arguments, function(acc, elem) { return acc.concat(elem) }, []);
return flattened;
};
In ES6, you can use Array.from()
to convert any iterable or array-like object to an actual array:
var flatten = function() {
var args = Array.from(arguments);
var flattened = args.reduce(function(acc, elem) { return acc.concat(elem) }, []);
return flattened;
};
Update in 2021 using modern language features:
function flatten(...args) {
return args.flat();
}
And, you can pass a depth to .flat(n)
(default is 1) if you want to flatten to a deeper level than just one level down.
Though, since we have these more modern features now built into the language, you probably can use them more directly rather than passing them to a function to work on them, but we'd have to see some particular use cases to make suggestions for inline ways to solve your problem rather than using this function.
FYI, there are lots of ways to flatten an array:
Merge/flatten an array of arrays
How to flatten nested array in javascript?
Flattening multidimensional Arrays in JavaScript
Array.prototype.flat() method
Use Array.prototype.concat.apply([], arguments)
function flatten() {
return Array.prototype.concat.apply([], arguments);
}
console.log(flatten([1, 2], 3, 4, [5, 6]));
If that looks ugly, and you don't mind creating an unused empty array, you can use:
[].concat.apply([], arguments)
In ES6 though, you can get the best of both worlds:
[].concat(...arguments)
I hope my answer is helpful, I know this post was from 2016.
function flatten(...args){
const values= args.reduce(function sumNumss(total,element){
return `${total} ${element}`
});
return values
}
flatten('sdfe',[1,23,1,23],'sedfe')
using rest of (...args) syntax for the argument should do the trick.
You can also test if elements are subArraythis way :
function flatten(arr){
var res = [];
arr.forEach(x => Array.isArray(x) ? x.forEach(y => res.push(y)) : res.push(x));
return res;
}
console.log(flatten([[1,2,3], 4, 5, [6, 7]])); // [ 1, 2, 3, 4, 5, 6, 7 ]
Something like this:
BTW: I think using push
is better than concat
, as this doesn't create a new array
function flatten()
{
return flatten0([], Array.from(arguments));
function flatten0(res, arrToFlatten)
{
for (let el of arrToFlatten)
Array.isArray(el) ? flatten0(res, el) : res.push(el);
return res;
}
};
let arr = [1, 2, [3, 4], [[5, [6], [[7]]]]];
console.log(flatten(arr)) // [ 1, 2, 3, 4, 5, 6, 7 ]