'How would you use .reduce() on arguments instead of a specific array or object?
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.
Solution 1:[1]
Convert 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?
Solution 2:[2]
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)
Solution 3:[3]
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.
Solution 4:[4]
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 ]
Solution 5:[5]
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 ]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | jrswgtr |
Solution 4 | kevin ternet |
Solution 5 |