Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the [].push.apply work?

can someone please explain me how does this line of code work.

[].push.apply(perms, permutation(arr.slice(0), start + 1, last));

This function generates an array of all permutations of an input array;

var permutation = function(arr, start, last){
  var length = arr.length;

  if(!start){
    start = 0;
  }

  if(!last){
    last = length - 1;
  }

  if( last === start){
    return [arr];
  }

  var temp;
  var perms = [];

  for(var i = start; i < length; i++){
    swapIndex(arr, i, start);
    console.log(arr);

    [].push.apply(perms, permutation(arr.slice(0), start + 1, last)); 

    swapIndex(arr, i, start);
  }

  return perms;
};
like image 350
Davis Davis Avatar asked Jul 18 '17 12:07

Davis Davis


2 Answers

[].push creates a new array, then fetches push which is the same as Array.prototype.push but with creating an unused object each time that needs to be garbage collected.

If you call Array.prototype.push(5) it wont work since this wouldn't be set to an array or something that extends an array. Thus you need to use either Function.call, Function.apply or Function.bind to set this if you want to use an arbitrary function to work as a method.

If you have Array.prototype.push.apply(thisObject, arrArguments) is the same as thisObject.push(arrArguments[0], arrArguments[1], ..., arrArguments[n]) if thisObject has push in its prototype chain. Since perms is an array and has push in it's own prototype chain it could be replaced with:

perms.push.apply(perms, permutation(arr.slice(0), start + 1, last));

The use of apply is because push gets all the contents of the permutations array as arguments. thus if permutations(....) returned [1,2,3] it would be synonymous with perms.push(1, 2, 3). You could write it without apply by calling push for each element:

for (var e of permutation(arr.slice(0), start + 1, last)) {
    perms.push(e);
}

And in ES6 you can simply use the spread syntax which is the same as apply but simpler to comprehend:

perms.push(...permutation(arr.slice(0), start + 1, last))
like image 119
Sylwester Avatar answered Oct 13 '22 01:10

Sylwester


Expanded it is the same as:

Array.prototype.push.apply(arrryToPushTo, ArrayOfItemsToPush)

apply() is from Function.prototype.apply() and Array.prototype.push is a function.

Using an empty array instead of writing "Array.prototype" exposes the push() method that apply() can be called on and is done simply because "[]" is less characters to write than "Array.prototype".

like image 37
charlietfl Avatar answered Oct 13 '22 02:10

charlietfl