Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between a regular push and an Array.prototype.push.apply

I don't quite understand the difference between the following two lines of code. In my code, the line with "apply" works the way I want it to, and the line with just regular push doesn't.

So what is really going on when both of these are executed:

//this one does not work the way i want it to
$scope.items.push(result.data.stuff)

//this one works!
Array.prototype.push.apply($scope.items, result.data.stuff);

Edit: sorry for confusion, I fixed it so that it has the "push" method in there

like image 436
user3092075 Avatar asked Feb 25 '16 21:02

user3092075


5 Answers

New 1. That pushes the array onto items.

$scope.items = [1, 2];
result.data.stuff = [3, 4];
$scope.items.push(result.data.stuff);
$scope.items[0] === 1;
$scope.items[1] === 2;
$scope.items[2][0] === 3;
$scope.items[2][1] === 4;

Old 1. Drops the existing reference that was in $scope.items.

$scope.items = [1, 2];
result.data.stuff = [3, 4];
$scope.items = result.data.stuff;
$scope.items[0] === 3;
$scope.items[1] === 4;

2. Pushes all the items from result.data.stuff into $scope.items, keeping the existing items.

$scope.items = [1, 2];
result.data.stuff = [3, 4];
Array.prototype.push.apply($scope.items, result.data.stuff);
$scope.items[0] === 1;
$scope.items[1] === 2;
$scope.items[2] === 3;
$scope.items[3] === 4;
like image 89
Daniel A. White Avatar answered Oct 05 '22 06:10

Daniel A. White


Basic difference is explained on Function.prototype.apply().

You can read there:

You can use push to append an element to an array. And, because push accepts a variable number of arguments, you can also push multiple elements at once.

But, if you pass an array to push, it will actually add that array as a single element, instead of adding the elements individually. So you end up with an array inside an array.

So if you do something like this:

let numbersArray = [1, 2]
numbersArray.push([3, 4])

You will have an array in array:

[1, 2, [3,4]]

When you have a list of variables which you want to add, you can use push.apply()

let numbersArray = [1, 2]
numbersArray.push.apply(numbersArray, [3, 4])

Then your result will looks like that:

[1, 2, 3, 4]
like image 31
Krzysztof Juszcze Avatar answered Oct 05 '22 07:10

Krzysztof Juszcze


Array.prototype.push() is a method that adds one or more elements to the end of the array and returns the new length of the array. Array.prototype.push.apply() takes the original array and an array which contains elements to add to the original array.

Example for Array.prototype.push():

var numbers = [1, 5, 2, 8];
numbers.push(3, 4, 6, 7);
console.log(numbers); // [1, 5, 2, 8, 3, 4, 6, 7]

Example for Array.prototype.push() with nested arrays:

var foods = [['apples', 'pears']];
foods.push(['lettuce', 'celery']);
console.log(foods); // [['apples', 'pears'], ['lettuce', 'celery']]

Example for Array.prototype.push.apply():

var grades = [90, 88, 83, 85];
var more_grades = [79, 84, 81, 90];
Array.prototype.push.apply(grades, more_grades);
console.log(grades); // [90, 88, 83, 85, 79, 84, 81, 90]

Example for Array.prototype.push.apply() with nested arrays:

var sports = [['running', 'cycling']];
var other_sports = [['football', 'basketball']];
Array.prototype.push.apply(sports, other_sports);
console.log(sports);
// [['running', 'cycling'], ['football', 'basketball']]

References:

push

apply

like image 34
exd5cxd4 Avatar answered Oct 05 '22 05:10

exd5cxd4


push() will add on one index for every argument you pass in. It does not care what it is adding to the array. What every you tell to add it will add it to the end of the array.

When you use apply(), it will take the array that you have supplied as the second argument and convert it to multiple arguments. MDN explains it well, but it basically turns it into

yourArray.push(argument[0],argument[1],argument[2],argument[3]);
like image 40
epascarello Avatar answered Oct 05 '22 07:10

epascarello


see:MDN:Function.prototype.apply();

Please note the note on this page:

Note: While the syntax of this function is almost identical to that of call(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.

The apply() method calls a function with a given this value, and arguments provided as an array (or an array-like object). All the items within the argsArray(second parameter) will be used for Array.prototype.push in order.It is the same to :

$scope.items.push.apply($scope.items, result.data.stuff);

Because $scope.items.push === Array.prototype.push and apply() accepts an array-like parameter but Function.prototype.call() accepts an arguments list;

Briefly speaking, apply will translate array-like parameter into pieces for that function.

like image 22
Chosan Avatar answered Oct 05 '22 07:10

Chosan