This question already has answers here:
Copy array by value
(39 answers)
Closed 8 years ago.
sorry very basic question I'm new.
If I have an array and pass it to a new variable (newArray = oldArray) then remove an element from newArray, it seems to also effect oldArray.
my guess is that it's simply creating a new reference to the same variable, so that data that was stored in oldArray now has two identifiers?
If so how do I actually pass the elements from oldArray into newArray so that newArray is independent from oldArray?
Thanks in advance
my guess is that it's simply creating a new reference to the same variable, so that data that was stored in oldArray now has two identifiers?
Right, both your new variable and your old one are pointing to the same array. Operations on the array through one reference (variable) are naturally visible through the other one, since there is just one array.
To avoid this, you'd have to make a copy of the array. There are several ways to do that, one of which is to use slice:
var newArray = oldArray.slice(0);
slice returns a shallow copy of an array starting at the given index. If you give it the index 0, it copies the entire array.
The quickest way is to use an array function to return a new array instance. Typically, I use:
var newArray = oldArray.slice(0);
In that case you have to clone the array using the slice method:
newArray = oldArray.slice(0);
As you've learned, when you copy an array variable, you copy a reference to the original.
Here's one idom to make a real copy - request a slice from the first element
var newArray = oldArray.slice(0);
Related
This question already has answers here:
Change the value of an array changes original array JavaScript
(3 answers)
Closed 5 months ago.
I was playing around with reverse() to see how it works and came across this interaction that I can't understand at all. Here is the initial code:
let muhArray = [1,2,3,4,5];
let reversedArray = muhArray.reverse();
console.log(`muhArray: ${muhArray}`);
console.log(`reversedArray: ${reversedArray}`);
This returns:
muhArray: 5,4,3,2,1 (Original array changed as well)
reversedArray: 5,4,3,2,1
I figured that since reverse() reverses arrays in-place, even if it is an initilization, it changes the original muhArray anyways. So I created a copy(muhArrayCopy) to preserve the original array.
let muhArray = [1,2,3,4,5];
let muhArrayCopy = muhArray;
console.log(`muhArrayCopy: ${muhArrayCopy}`);
let reversedArray = muhArray.reverse();
console.log(`reversedArray: ${reversedArray}`);
This returns:
muhArrayCopy: 1,2,3,4,5
reversedArray: 5,4,3,2,1
Up until this point everything seems fine, but changing the order made me realise muhArray.reverse() affects already declared and initialized muhArrayCopy as well.
let muhArray = [1,2,3,4,5];
let muhArrayCopy = muhArray;
let reversedArray = muhArray.reverse();
console.log(`muhArrayCopy: ${muhArrayCopy}`);
console.log(`reversedArray: ${reversedArray}`);
Such order returns:
muhArrayCopy: 5,4,3,2,1
reversedArray: 5,4,3,2,1
Is this maybe a code execution order thing? I have read about hoisting but that does not seem to explain it, as far as I can understand. I am all new to programming so I have little to no knowledge about it.
Thanks in advance.
js is call by reference, so
let muhArrayCopy = muhArray;
does not create a copy, it puts the reference of variable in the other one, so both are affected when something happens to the other.
let muhArray = [1,2,3,4,5];
let muhArrayCopy = [...muhArray];
let reversedArray = muhArray.reverse();
console.log(`muhArrayCopy: ${muhArrayCopy}`);
console.log(`reversedArray: ${reversedArray}`);
this should solve it. here [...muhArray] we are creating a copy of the array.
There is nothing unexpected happening here. In the first code snippet, you print the array copy before reversing the original array. Keep in mind that the "copy" still points to the original array. In the second snippet, you print the copy after reversing the original source.
[Array.prototype.reverse()][1] from definition The reverse() method reverses an array in place and returns the reference to the same array
So when you apply reverse to an array, it changes the parent array as well.
If you want to make your original array unchanged, you have to copy the original array to an another memory location and reverse it.
Assigning a variable to another will copy the memory location of the same variable. So what ever changes made to the existing variable will be reflected to the assigned variable as well
You should not copy the variable, instead you have to clone it and assign it to another variable. This can be done using Deep Copy and Shallow Copy
Read more about Deep Copy v/s Shallow Copy here
Since the variable here is an array, just clone it with Spread operator and reverse it.
Working Example
let muhArray = [1,2,3,4,5];
let muhArrayCopy = muhArray;
let reversedArray = [ ...muhArray ].reverse();
console.log(`muhArrayCopy: ${muhArrayCopy}`);
console.log(`reversedArray: ${reversedArray}`);
I have this question whereby I need to set up an array without any loops.
I have no idea as to where to start. I was thinking of creating the array with the desired length first and then put the elements in it. However, I don't think that'll work because it'll mean that I have to hardcode the array with the desired length?
Here's an example of creating an array that contains 3 empty arrays with .fill() and .map()
let arr = new Array(3).fill().map(()=>new Array())
.fill() is needed so that you can have values to map, .map() creates new arrays. Note that calling something like .fill(new Array()) won't work well, because it will populate it with references to the same array.
I am making a small game in JavaScript to help me learn it. The game is based around an array of tiles, each with different values.
When it starts, it puts an object into each cell, then goes on to the next, changing the values.
It always shows the properties of the last cell. Is there any way I can have the cells have different values without making tons of different objects?
Sorry if the question isn't clear. I'm very new to JavaScript.
You don't need to worry about the objects and there is few ways to declare array and work with it. You can follow the javascript doucemntation.
If you are not satisfy the documentation there is some array examples to understand the value changing and objects changing.
JavaScript Array: Explained with uses in different components
JavaScript Pass By Value And Pass By Reference In JavaScript
JavaScript Arrays - tips, tricks and examples
If you have any question comment below.
I think you are pushing the same object over and over into the array. Use the spread operator to essentially clone the object in place while changing the values you need.
const array = []
const obj = { a: 5, b: 6 };
array.push(obj);
array.push(obj);
obj.b = 8;
array.push({ ...obj, b: 10 })
console.log(array[0], array[1], array[2]);
As you see, obj.b=8 affects both the first and second elements of the arrays as they are both referring to the same object. But since the spread (...) operator is cloning the object, only the last element has b=10
This question already has answers here:
Copy array by value
(39 answers)
Closed 9 years ago.
I'm trying to save a copy of the array before I sort it:
words_Array = ["Why", "doesnt", "this", "work?"];
var sortedWords_Array = words_Array;
sortedWords_Array.sort(function(a, b){
return b.length - a.length;
});
alert("sortedWords_Array is :"+sortedWords_Array);
alert("words_Array is :"+words_Array);
After I sort sortedWords_Array, they're both sorted for some reason. http://jsfiddle.net/zv39J/ Why is that?
Because in javascript, arrays are passed by reference which means that when you make one array equal to another it will change both whenever you make an edit to one. To fix this in your example change the following line:
var sortedWords_Array = words_Array;
to:
//make a copy of array by using slice
var sortedWords_Array = words_Array.slice(0);
See here for other uses and a more in-depth explanation:
slice does not alter the original array, but returns a new "one level
deep" copy that contains copies of the elements sliced from the
original array.
Array.prototype.slice()
Do a slice() on the array to duplicate, and then sort.
var sortedWords_Array = words_Array.slice();
Use the slice function to make a fast copy.
http://jsfiddle.net/zv39J/2/
On another note—alerts are terrible. No one wants to click a jsfiddle only to be greeted by a series of alert windows. I've updated the fiddle to include jQuery, which allows us to use a nice succinct syntax to make updates to the HTML.
This wont work because when you try to assign
var sortedWords_Array = words_Array;
The reference of words_array is passed to sortedWords_Array. So any change made to sortedWords_Array will be reflected on words_array.
Since Array.slice() does not do deep copying, it is not suitable for multidimensional arrays:
var a =[[1], [2], [3]];
var b = a.slice();
b.shift().shift();
// a is now [[], [2], [3]]
Note that although I've used shift().shift() above, the point is just that b[0][0] contains a pointer to a[0][0] rather than a value.
Likewise delete(b[0][0]) also causes a[0][0] to be deleted and b[0][0]=99 also changes the value of a[0][0] to 99.
jQuery's extend method does perform a deep copy when a true value is passed as the initial argument:
var a =[[1], [2], [3]];
var b = $.extend(true, [], a);
b.shift().shift();
// a is still [[1], [2], [3]]
Here's some code that has two arrays(np and op), one a copy of the other
However, when I modify the copy, the original is also modified!
take a look:
<script type="text/javascript">
var op=new Array(0, 0);
var np=op;
np[1]=2;
document.write(op+"<br>")
document.write(np)
</script>
Is there any way to retain the original and modify the copy?
Some of the built in Array functions will actually create a copy for you. One such is slice.
For example:
var op=new Array(0, 0);
var np= op.slice(0);
np[1]=2;
document.write(op+"<br>")
document.write(np)
Reference http://my.opera.com/GreyWyvern/blog/show.dml/1725165
You never made a copy of the array. You simply assigned the array to another variable. This does not copy in Javascript. In your example there is only one array with two variables by which you can access it. There is no built-in way to copy arrays in Javascript so you will need to write your own function to do it.
Take a look at this StackOverflow question for a hint on how to actually implement the copying of the elements in the array.
What you are doing is not creating a copy of the array, it's only creating a copy of the reference to the array, so you get two references to the same array object.
This is how you can create an actual copy of the array:
var np = op.concat();
The concat method creates a new array that is a copy of the array with any additional items added. If you don't specify any additional items you just get a copy of the array.
Array.prototype.copy = function() {
return this.slice(0, this.length);
}
Then
var op=new Array(0, 0);
var np=op.copy();
np[1]=2;
document.write(op+"<br>")
document.write(np)
You should clone the second array instead of copying it.
--- Update
If you assign an object to a variable, only the reference is copied (that means, they both point to the same data). For having an independent copy of this object you need to clone it. And there are several ways how to this, for example here is the way of cloning object using jQuery.
You can just use the native slice method which returns a copy of the array:
var np = op.slice(0,op.length);
The second parameter should be optional, but in IE I believe it is required.
Your code, complete with the change:
var op=new Array(0, 0);
var np=op.slice(0,op.length);
np[1]=2;
document.write(op+"<br>")
document.write(np)
To create a new array you might want to consider:
var op = [];
To copy an array:
var np=op.slice();
or
var np=op.concat();
concat is faster, while slice takes up one less character. Some people alias "slice" or "concat" as "copy" so that it's more obvious that you're making a copy.
No need for parameters in either case. Parameters in the slice will just make the code larger and slower.