Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

change values in array when doing foreach

example:

var arr = ["one","two","three"];  arr.forEach(function(part){   part = "four";   return "four"; })  alert(arr); 

The array is still with it's original values, is there any way to have writing access to array's elements from iterating function ?

like image 967
rsk82 Avatar asked Sep 18 '12 18:09

rsk82


People also ask

Can you modify array in forEach?

To change the value of all elements in an array:Use the forEach() method to iterate over the array. The method takes a function that gets invoked with the array element, its index and the array itself. Use the index of the current iteration to change the corresponding array element.

Can you use forEach on an array?

The forEach method is also used to loop through arrays, but it uses a function differently than the classic "for loop". The forEach method passes a callback function for each element of an array together with the following parameters: Current Value (required) - The value of the current array element.


2 Answers

The callback is passed the element, the index, and the array itself.

arr.forEach(function(part, index, theArray) {   theArray[index] = "hello world"; }); 

edit — as noted in a comment, the .forEach() function can take a second argument, which will be used as the value of this in each call to the callback:

arr.forEach(function(part, index) {   this[index] = "hello world"; }, arr); // use arr as this 

That second example shows arr itself being set up as this in the callback.One might think that the array involved in the .forEach() call might be the default value of this, but for whatever reason it's not; this will be undefined if that second argument is not provided.

(Note: the above stuff about this does not apply if the callback is a => function, because this is never bound to anything when such functions are invoked.)

Also it's important to remember that there is a whole family of similar utilities provided on the Array prototype, and many questions pop up on Stackoverflow about one function or another such that the best solution is to simply pick a different tool. You've got:

  • forEach for doing a thing with or to every entry in an array;
  • filter for producing a new array containing only qualifying entries;
  • map for making a one-to-one new array by transforming an existing array;
  • some to check whether at least one element in an array fits some description;
  • every to check whether all entries in an array match a description;
  • find to look for a value in an array

and so on. MDN link

like image 166
Pointy Avatar answered Oct 12 '22 00:10

Pointy


Let's try to keep it simple and discuss how it is actually working. It has to do with variable types and function parameters.

Here is your code we are talking about:

var arr = ["one","two","three"];  arr.forEach(function(part) {   part = "four";   return "four"; })  alert(arr); 

First off, here is where you should be reading about Array.prototype.forEach():

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Second, let's talk briefly about value types in JavaScript.

Primitives (undefined, null, String, Boolean, Number) store an actual value.

ex: var x = 5;

Reference Types (custom objects) store the memory location of the object.

ex: var xObj = { x : 5 };

And third, how function parameters work.

In functions, parameters are always passed by value.

Because arr is an array of Strings, it's an array of primitive objects, which means they are stored by value.

So for your code above, this means that each time the forEach() iterates, part is equal to the same value as arr[index], but not the same object.

part = "four"; will change the part variable, but will leave arr alone.

The following code will change the values you desire:

var arr = ["one","two","three"];  arr.forEach(function(part, index) {   arr[index] = "four"; });  alert(arr); 

Now if array arr was an array of reference types, the following code will work because reference types store a memory location of an object instead of the actual object.

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];  arr.forEach(function(part, index) {   // part and arr[index] point to the same object   // so changing the object that part points to changes the object that arr[index] points to    part.num = "four"; });  alert(arr[0].num); alert(arr[1].num); alert(arr[2].num); 

The following illustrates that you can change part to point to a new object while leaving the objects stored in arr alone:

var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];  arr.forEach(function(part, index) {   // the following will not change the object that arr[index] points to because part now points at a new object   part = 5; });  alert(arr[0].num); alert(arr[1].num); alert(arr[2].num); 
like image 36
Dave Avatar answered Oct 12 '22 02:10

Dave