I am passing an array of objects to a function whose role is to remove some of those objects according to some sort of criterium.
The problem is that the scope isn't being handled the way I would like it to be, and the original array is not being updated.
In that function, the return value is already used and may not be changed. How might I be able to change the array?
A variable pointing to an array is a reference to it. When you pass an array, you're copying this reference. So you should just modify the array parameter and it will modify the original array.
var a=[1,2,3];
var c=f(a);
alert(a); // a is now [1,2,3,6]
function f(b) {
b.push(6);
return 1;
}
Related
I've attempted to define a randomize method to Array.prototype like so :
Array.prototype.randomize = function() { // Yes, this method does cause the array to have 'holes', but its good enough for this example/demonstration
var r = new Array(this.length); // Possible but somewhat unwanted to randomize the array in its place, therefore it has to be set to this new array later on.
this.forEach(function(e) {
r[Math.floor(Math.random() * r.length)] = e;
});
// how do I set 'this' to the variable r? (In order to change the array to the new and randomized array 'r')
return r;
}
This method does return the randomized array, but how do I change the array itself as well?
As the comments say, changing an array in place in place is a better way to shuffle.
But if you did need to replace all of the elements in one go, you could use Array#splice:
Array.prototype.randomize = function() {
var r = /* the algorithm to get a replacement array... */;
this.splice(0, r.length, ...r);
return this;
}
... is the spread operator. It's part of ES2015.
Spread operator compatibility table
not possible to randomize the array in its place
Wrong.
how do I set 'this' to the variable array 'r' in order to change the array to the new one?
That's impossible in JavaScript. You cannot overwrite an object, not via the this reference and not via a normal variable, you have to actually mutate its properties. If you want to overwrite the variable in which the array reference is stored, you need to explicitly assign to that variable; you cannot do it via a method (since JS does not allow pass-by-reference) and you can only overwrite this reference, not all variables that might contain it.
I have an array of objects as follows:
var myarray=[{"name":"John","address":"home"},{"name":"Peter","address":"home"}]
and I would like to run a function to add a property to the array as follows:
[{"name":"John","address":"home","collection":"friend"},
{"name":"Peter","address":"home","collection":"friend"}]
I have tried doing this:
myarray=myarray.map(function (err, myarray){
myarray.collection="friend";
return myarray;
}
console.log(myarray)
But the console continues to return this:
[{0},{1}]
Can anyone help me? Thank you
Your code is not adding the property to the contents of the array. The values of the array are given as the first parameter to the callback function (the second parameter is an index, and not the array itself—that's the third parameter). Simply assign the new property to the first parameter of the callback function, rather than the second one.
Edit - As #zerkms points out, however, if you're looking to update the current array rather than generate a new array, map is probably not best solution here. forEach provides a method for iterating over the current array, and modifying each of its values (which is what you're doing). This would looks omething like this:
myarray.forEach(function(value) {
value.collection = "friend";
});
As you'll notice in the documentation for .map, the callback function returns the new value that will appear in the new array that is generated by map; if you're changing the current array in place (i.e. by modifying the properties of its contents), there's no need to return anything.
myarray.map(function(value) {
value.collection = "friend";
});
Also note that both map and forEach are methods, so you need to close the method invocation with ).
Wrong use of map().
The first argument of map() is the current element of the array, the second argument is it's index.
For example:
['a','b','c'].map(function(element, index){console.log(element, index)});
Will result in
a 1
b 2
c 3
So inside your function myarray was your index, and you were trying to add the property to the index.
Now you have to options. Either you use the map() as it's ment to be used and assign it's return value to myarray:
myarray = myarray.map(function(element) {
element.collection = "friend";
return element;
});
or you can, because objects are not getting copied but referenced when passed as an argument, not care about the return values and modify the elements directly:
myarray.map(function(element) {
element.collection = "friend";
}); // returns [undefined, undefined ...]
This, however, isn't the way one should use map()
Better: Use forEach()
myarray.forEach(function(element) {
element.collection = "friend";
});
Hope it helped.
Greets!
All you have to do is changing the reference object within map function
myarray.map(function (value){
value.collection = "friend";
});
console.log(myarray);
In JavaScript, how do I mutate the value of an array inside of a function? I know that happens when using certain array methods, but it doesn't seem to work for normal assignment.
var arr = [4]
function changeArray(arr) {
arr = [1,2,3];
}
// arr is still equal to [4]. I want it to equal [1,2,3].
It's my understanding that this code doesn't change the value of "arr" outside of the function. How can I do it in a way that mutates the array that was passed as an argument?
You can use .splice:
arr.splice(0, arr.length, 1, 2, 3);
Or you can empty the array and .push the values:
arr.length = 0;
arr.push(1, 2, 3);
// or given an array of values
arr.push.apply(arr, newValues);
However, make sure it is clear that the function changes the array in place. While there are native functions that does this (like Array#sort), I'd argue that this is not as common as simply returning a new array.
It's my understanding that this code doesn't change the value of "arr" outside of the function.
Correct. Assigning a new value to a variable or property never changes the value of another variable or property (exceptions: global scope and with statements).
You basically tried to change the value of a variable, not mutate the value itself.
JavaScript is call/pass/assign by value (Wikipedia also mentions "by sharing"), not by reference.
I need to change array to a new array created inside a function.
function changeArr(a)
{
a=["hello"]; // don't work
//a.push("hello"); //works, but the real array pretty big (dont want copy)
}
var arr=[];
changeArr(arr);
console.log(arr); // should echo ["hello"]
It seems like all you really want to do is clear the array that is passed into the function, before appending to it:
function changeArr(a)
{
a.length = 0; // clear the array here if you don't care about the prev. contents
a.push("hello"); // this adds to the array that was passed in
}
Inside the function changeArr(), a is only a local variable referencing the array you passed as an argument when calling this function. a=["hello"] makes this local variable reference a newly created and different array. This changes does not affect the original array passed in. What you want to do is likely what Miky Dinescu suggested: use the local variable to modify the original array but don't assign/attach anything new to it.
If you are trying to completely replace the array, you can use a return value.
function changeArr()
{
return ["hello"];
}
arr = changeArr();
If there is a reason you aren't doing this, explain and I'll adjust my answer.
You can use the splice method as such:
a.splice(0,a.length,"hello")
I am using JavaScript. I have an object. I then place that object inside an array that I initialize. I then do some work on that array and the value(s) inside it. I'm hoping to know if, by changing the object in the array, I am also changing the actual object itself? Code below.
function doStuff() {
var node = getNode(); //getNode() returns a node object
var queue = [node]; //This is the line my question is about
while(queue.length > 0) {
//Add data to queue[0]. Add queue[0]'s children to queue, remove queue[0]
}
return node;
};
So, when the while loop finishes, will node be pointing to the changed object, or will it just hold a copy of the object from before it was put into the queue?
I appreciate any help, many thanks!
Objects in Javascript are always assigned by reference, they're never copied automatically.
You could check it yourself:
var obj = {a: 1, b: 1};
var arr = [obj];
arr[0].a = 0;
alert(obj.a) // Result: 0;
http://jsfiddle.net/pnMxQ/
I have an object. I then place that object inside an array that I initialize.
No, you don't. "Objects" are not values in JavaScript. You have a reference (pointer to an object). You place that inside the array. node is a reference. queue is a reference. getNode() returns a reference. Once you realize that, it becomes simple.