简体   繁体   中英

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 .

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;
};

FYI, there are lots of ways to flatten an array:

Merge/flatten an array of arrays in JavaScript?

How to flatten nested array in javascript?

Flattening multidimensional Arrays in JavaScript

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 ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM