Comparing and copying arrays in JavaScript is a pain
Ever wanted to copy an array in JavaScript? Tried the simple var array2 = array1?
Yes, it doesn't work that way.
Apparently with arrays and objects, JS uses references just like C# and in case you want to make a copy of an array...
function CopyArray(a)
{
//Create a new array with the old ones length
var n = new Array(a.length);
//Just copy all the values from the old to the new
for(var i = 0; i < a.length; i++)
n[i] = a[i];
return n;
}
var array2 = CopyArray(array1);
You'll have to use something like that. Of course it gets way more complicated when dealing with jagged arrays, eg. arrays which have arrays in them. You'll have to write a recursive function or something the like of this:
function CopyArray(a)
{
//Create a new array with the old ones length
var n = new Array(a.length);
//Just copy all the values from the old to the new
for(var i = 0; i < a.length; i++)
{
//if the value in the old array is an object (array)
//call the CopyArray function recursively
if(typeof a[i] == 'object')
n[i] = CopyArray(a[i]);
else
n[i] = a[i];
}
return n;
}
With that you can create nice copies of arrays while still keeping them as array objects.
How about comparing arrays? Uh oh, if(a == b) doesn't work like expected!
Yet again we'll have to use a customized function
//Check if two arrays' contents are the same
//returns true if they are, otherwise false
Equals = function(a,b)
{
//Check if the arrays are undefined/null
if(!a || !b)
return false;
//first compare their lengths
if(a.length == b.length)
{
//go thru all the vars
for(var i = 0; i < a.length;i++)
{
//if the var is an array, we need to make a recursive check
//otherwise we'll just compare the values
if(typeof a[i] == 'object') {
if(!Equals(a[i],b[i]))
return false;
}
else if(a[i] != b[i])
return false;
}
return true;
}
else return false;
}
if(Equals(a,b)) { /* ... */ }
ookay!
You might notice that the usual JavaScript naming convention is that function names start with a small letter. I use capital letters just because I'm used to that from C# and it looks better to my eye.
9 Comments:
I always wondered about this. Thanks for the explanation!
By Anonymous, at 12:29 PM
Easier solutions.
To copy an array:
var array1 = array2.slice();
To compare them:
if (array1.toString() == array2.toString()) alert("they're equal");
By Anonymous, at 10:21 PM
and if order doesn't matter when comparing:
if (array1.sort().toString() == array2.sort().toString())
alert("they are equal unordered arrays");
By Anonymous, at 5:47 AM
I haven't tried your method yet but I created my own and wanted to share it with someone.
I need to compare objects that can contain other objects, strings, or arrays and I don't care about the order in which array values are listed.
So here's what I have and it works well. Hope it helps someone or maybe someone can tell me how I could have done this an easier way.
/**
Compares two objects. The objects can contain other objects, strings, or arrays.
It cannot determine the equality of function types. It has not been tested
with DOM elements.
**/
compare: function(item1, item2) {
var equals = false;
var exit = false;
try {
if(this.isObject(item1)&&this.isObject(item2)) {
if(this.isArray(item1)==false&&this.isArray(item2)==false) {
for (var p1 in item1) {
for(var p2 in item2) {
if(item2[p1]) {
if(this.isObject(item1[p1])==true&&this.isObject(item2[p2])==true) {
equals = this.compare(item1[p1], item2[p2]);
} else {
if(p1==p2) {
if(item1[p1]==item2[p2]) {
equals = true;
} else {
exit = true;
break;
}
}
}
}
}
if(exit==true) {
break;
}
}
} else {
if(item1.length&&item2.length) {
if(item1.length==item2.length) {
for (p3 in item1) {
for(p4 in item2) {
if(item2[p3]) {
if(this.isObject(item1[p3])==true&&this.isObject(item2[p4])==true) {
equals = this.compare(item1[p3], item2[p4]);
} else {
if(p3==p4) {
if(item1[p3]==item2[p4]) {
equals = true;
}
} else {
exit = true;
break;
}
}
}
}
if(exit==true) {
break;
}
}
} else {
equals = false;
}
} else {
equals = true;
}
}
} else {
if(item1==item2) {
equals = true;
}
}
}catch(ex) {
equals = false;
}
return equals;
},
isObject: function(obj) {
return typeof(obj)=='object';
},
isArray: function(obj) {
if (obj.constructor.toString().indexOf("Array") == -1) {
return false;
} else {
return true;
}
}
By Anonymous, at 11:00 AM
to copy array
var arrName = ["jack","jill"];
var copy_of_arrName = eval(arrName.toString());
similarly you can compare arrays too...
By Anonymous, at 1:57 PM
>if (array1.toString() == >array2.toString()) alert("they're >equal");
Wow!!
So:
array1 = ["a,b"];
array2 = ["a","b"];
and they are equal!
incredible!
This is an easier way to go WRONG.
By Francesco, at 12:49 PM
Copying an array is much simpler than that:
array2 = array1.slice();
By Ricardo Tomasi, at 12:10 AM
Be careful about naming your functions with a Capital letter, because in JavaScript we normally start with a Capital letter when the function needs to be instantiated (ie a constructor function). This is because since in JavaScript there is no compile-time errors, the naming convention is only thing we have.
By Andreas Grech, at 12:14 PM
Thanks a lot.
It's saves my time
By Anonymous, at 12:33 PM
Post a Comment
<< Home