How to retain array in javascript? - javascript

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.

Related

JavaScript scoping (copying one array to another)

In this code... mapObj.fetchTimeObjs should NOT change right?!?!
Somehow mapObj.fetchTimeObjs gets changed when this function is run:
function clockErasePast(){
var now = new Date().getTime();
var tmpFetchTimeObjs = [];
for(var i =0; i<mapObj.fetchTimeObjs.length; i++){
tmpFetchTimeObjs.push(mapObj.fetchTimeObjs[i]);
if(mapObj.fetchTimeObjs[i].start < now){tmpFetchTimeObjs[i].start = now;}
}
return tmpFetchTimeObjs;
}
tmpFetchTimeObjs[i]
will contain only reference to the mapObj.fetchTimeObjs[i].
If you will change tmpFetchTimeObjs[i], the mapObj.fetchTimeObjs[i] will be changed, because you will have only one object which has two references. And if it will changed from one reference, it will be changed for the second reference too.
Let's consider an object which has two references. Here I change the object from one reference, and get the update for the second reference, because they refer to the same object.
var objA = { name: 'Bob', age: 25};
var objB = objA;
objB.age = 30;
console.log(objA.age);
To get independent object you need to create them. You can use Object.assign() function, which will copy any enumerable properties from into the destination(first parameter) object and returns it.
You can create with
var obj = Object.assign({}, mapObj.fetchTimeObjs[i]);
tmpFetchTimeObjs.push(obj);
The objects you push to the new array, are the same as the original array has, so if you mutate them, that mutation is visible to both arrays. This is what is called doing a shallow copy.
You could make a copy at one deeper level, where you would also create new objects and copy the original object's properties (like start) into those new objects. This you can easily do with Object.assign:
tmpFetchTimeObjs.push(Object.assign({}, mapObj.fetchTimeObjs[i]));
If these objects themselves have nested objects, then the problem you had would occur at deeper levels. If this is an issue, then you should look to deep clone solutions, like provided in this Q&A.
You need to clone the TimeObjs, since variables only keep the reference to the TimeObjs. We don't know the structure of your TimeObjs, so if the TimeObjs doesn't contain other objects, Object.assign() will work, otherwise maybe you need a deep clone method, such as jQuery.extend().

javascript pointers array or #define for abbreviation

I have a multi-dimensional array with different types of variables, like this:
array = [ [[file, name, visible], [ArrayPoint, ArrayOther], ...], [[file2,...], ..] ]
now in my code multiple times I have to call (for example) an Array() of points which is located in myArray [X] [1] [0].
I wanted to know if there was the possibility of creating definitions or pointers to the array position to shorten the code, because often I do not remember the variable positions.
// access the value at the address available in pointer
var *pointArray = &myArray[X][1][0];
// my code
*pointArray.push(pint_x, point_y);
============== VS ==============
myArray[X][1][0].push(pint_x, point_y);
thank you very much!! and good evening.
by Marco.
If you do
var pointArray = myArray[X][1][0];
It will make a copy of the reference to the array at myArray[X][1][0]. Therefore, any subsequent mutations to the elements of pointArray will also change the elements of myArray[X][1][0].
Note that reassigning a new value to pointArray as a whole would not effect myArray[X][1][0], since that would only make pointArray store something else.
Assignments do not copy/clone objects in JavaScript, they only make the variable on the left-hand side reference the same object as what's on the right-hand side.
var outer = [[0,1,2],[3,4,5]];
var inner = outer[1];
inner.push(6);
console.log(JSON.stringify(outer));
inner = [];
console.log(JSON.stringify(outer));
ok, thanks I understand.
my problem was that I created the variable called before filling the main array.
this is because I create the empty array structure, but is filled successively by the program events.
now to solve the problem I create the connection variable after the first event push to the primary array.
thank you very much for your availability.

Shifting the new variable also shifts the old original one

How come with this
var prodataTemp = [];
prodataTemp = prodata;
prodataTemp.shift();
both variable prodatTemp and prodata are shifted? I can see it in the console.
Assigning a JavaScript object to another variable, will not copy the contents, but it make the left hand side variable, a reference to the right hand side expression. So,
var prodataTemp = [];
made prodataTemp refer an empty array and then
prodataTemp = prodata;
makes prodataTemp refer the same array object prodata was pointing to. (So, the old empty array is no more referenced by prodataTemp).
To actually make a copy**, use Array.prototype.slice, like this
prodataTemp = prodata.slice();
Now, prodataTemp refers to the copy of the array prodata, so that shifting one will not affect the other.
** - The copy made is just a shallow copy. So, if you have an array of arrays, then a new array will be created with all the references to the elements of the old array. So, mutating one array element will have its impact in the other as well.

How to keep a variable from changing in javascript

I want to keep the original information of a variable so that a reset of the code will be much easier.
var $dataSets = [1,2,3,4];
var $oldData = $dataSets;
$('.button').click(function(){
$(this).toggleClass('selected');
if($(this).hasClass('selected')) {
$dataSets.splice(1,1);
console.log($dataSets);
} else {
console.log($oldData);
}
});
The problem I have with my code is that when I modify $dataSets it also changes $oldData. How do I keep $oldData from changing?
change to
var $dataSets = [1,2,3,4];
var $oldData = $dataSets.slice();
JavaScript does not pass the value of $dataSets into $oldData, rather it passes a reference to the thing which $dataSets itself references.
This workaround works because JavaScript's Arrays (which is what $dataSets is) have a method called slice which, when called with no parameters, returns a copy of the array.
You can use the function Array.slice(), like this:
var $dataSets = [1,2,3,4];
var $oldData = $dataSets.slice();
As described in the documentation, slice() does not alter the original array, but returns a new one. So basically, using slice, you have two different arrays, and can insert/remove items in one without interfering with the other.

Passing a JS Array to a new Array [duplicate]

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);

Categories