1

I'm working in a function and I need to turn all function's arguments in just one array, even if one argument is an array (or something with a list of values). I need something like array_merge() in PHP, but keys is not needed, just values that I wanted.


Edit 1:
I'm not looking for how turn object arguments into Array. I need all values passed as argument into single array. If one or more arguments is an array or object, its values need to be merged to one array. Like the example provided.


For example:
foo('bar', function, [1,2,3], [NodeList], window);
array => ['bar', function, 1, 2, 3, < HTMLElement>, < HTMLElement>, window]

Pay attention on [NodeList], it must turn into HTMLElements.

Done so far:
I've done this function below, but I wanna know if its a better way. Any comments/hints are appreciated.

function toArray(obj) {
  var k = Object.keys(obj);
  var i = 0, l = k.length;
  if (isString(obj) || l == 0 || obj === window) {
    return obj;
  } else {
    var objs = [];
    while (i < l) {
      objs = objs.concat(toArray(obj[k[i]]));
      i++;
    }
    return objs
  }
}
function isString(obj){
  return (typeof obj === 'string' || obj instanceof String);
}

Edit 1:
usage:

var arg1 = 'bar',
    arg2 = [1,2,3],
    arg3 = document.querySelectorAll('body');

foo(arg1, arg2, arg3) {
   var myArray = toArray(arguments);
   //myArray: ['bar', 1, 2, 3, <body>]
}
Vagner
  • 887
  • 1
  • 10
  • 15
  • JavaScript functions have a built-in object called the [arguments](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments) object. The argument object contains an array of the arguments used when the function was called. So, aacees this `arguments` from within function. – The Alpha Feb 08 '16 at 20:05
  • var args = Array.prototype.slice.call(arguments); – charlietfl Feb 08 '16 at 20:07
  • 1
    I feel the question is more about how to flatten arrays than to turn the arguments object into an array. He's also trying to flatten out object properties. – MinusFour Feb 08 '16 at 20:11
  • @charlietfl, pls remove duplicate, its not the case. Look at my example, [NodeList] needs to turn out to HTMLElements. As I said, is something like `array_merge()` in PHP. – Vagner Feb 08 '16 at 21:40

1 Answers1

2

Use the keyword arguments

http://www.w3schools.com/js/tryit.asp?filename=tryjs_function_arguments

function findMax() {
  var i;
  var max = -Infinity;
  for (i = 0; i < arguments.length; i++) {
    if (arguments[i] > max) {
      max = arguments[i];
    }
  }
  return max;
}
document.getElementById("demo").innerHTML = findMax(4, 5, 6);
<p>Finding the largest number.</p>
<p id="demo"></p>

Edit

This is how you flatten an array.

var arg1 = document.querySelectorAll('p');
var arg2 = 3;
var arg3 = [1, 2, [3, 2, 3, [45, arg1]]];
var arg4 = function() {};
var arg5 = {
  a: {
    b: 3,
    c: 2
  }
};
var arg6 = window;

function flatten() {
    /*gets all the arguments past in*/
    var arrays = arguments;
    var last = 0;
    /*flattens the array*/
    while (arrays.length != last) {
      last = arrays.length;
      arrays = [].concat.apply([], arrays);
    }
    /*maps all nodelist to an array*/
    arrays = arrays.map(function(obj) {
      var arg1 = [];
      if (isNodeList(obj)) {
        [].forEach.call(obj, function(node) {
          arg1.push(node);
        });
        return arg1;
      } else {
        return obj;
      }
    });
    /*flattens all node list arrays*/
    last = 0;
    while (arrays.length != last) {
      last = arrays.length;
      arrays = [].concat.apply([], arrays);
    }
    /*Returns unique array*/
    return unique(arrays);
  }
  /*Makes array unique*/

function unique(a) {
  return a.reduce(function(p, c) {
    if (p.indexOf(c) < 0) p.push(c);
    return p;
  }, []);
}

function isNodeList(obj) {
  var objType = {}.toString.call(obj);
  return (objType === '[object NodeList]' ||
    objType === '[object HTMLCollection]' ||
    objType === '[object Object]' && /^\s?function/.test(obj.item)) && obj.length; // returns length of nodeList if true      
};

document.getElementById('r').innerHTML = flatten(arg1, arg2, arg3, arg4, arg5, arg6);
<p id="s">

</p>
<p>

</p>
<span id='r'></span>
Roger
  • 3,226
  • 1
  • 22
  • 38
  • Thanks, but its not I'm asking for. Look at my example, I need just one flatten array. In this case `foo('bar', [1,2,3])` turn into array => ['bar', [1,2,3]]. – Vagner Feb 08 '16 at 21:37
  • @Vagner I edited my answer. This flattens arrays and nodelists. It does not flatten objects. – Roger Feb 09 '16 at 15:01