Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

copy array? 1

Status
Not open for further replies.

shadedecho

Programmer
Oct 4, 2002
336
US
anyone know of a simple straightforward way of copying an array (of n dimensions) to another variable, NOT just copying the reference to it.

I create an array of more than one dimension, with associative indexes, like so:

Code:
var blah = new Array();
blah["abc"] = new Array();
blah["abc"]["def"] = 1;
blah["abc"]["ghi"] = 2;

blah["def"]["ghi"] = 1;
blah["def"]["jkl"] = new Array();
blah["def"]["jkl"][0] = 1;
blah["def"]["jkl"][1] = 3;

now, I want to be able to make a copy of that array over to a variable called blah2.

Code:
var blah2 = blah;

This actually appears to be copying a reference, because if I then execute:

Code:
delete blah2["def"];

I would expect it to have only affected the copy of the original, not the original. But this is not the case. The original is also affected.

so, then I though I could do something like:

Code:
var blah2 = new Array(blah);

Unfortunately, though the documentation and some online examples seem to suggest this will work, it does not, it appears to only copy the first dimension over. Also, it seemed like maybe associative references were not copied/respected in that copy.

So, I being a very (re)invent-the-wheel kinda guy, decided to write a recursive function that would do a generic copy of an array of any dimension depth. This is what I came up with, and so far it seems like it works, though it's admittedly a little dirty.

Code:
function copyof(arrayObj) {
  var temp = null;
  if ((typeof arrayObj == "object") && (arrayObj.length > 0)) {
    temp = new Array();
    for (var index in arrayObj) {
      if (typeof arrayObj[index] == "object") {
        temp[index] = copyof(arrayObj[index]);
      }
      else temp[index] = arrayObj[index];
    }
  }
  return temp;
}

My question is this.... isn't there any better way to do this? This seems like the brute-force way of doing it, by creating a whole new array bit by bit, and force-copying each element into it. Surely javascript has a better way?

BTW, I originally thought it would be nice and elegant to have this be an object-oriented method that I could assign to the array object that let it duplicate itself.

Code:
blah.prototype.copyof = copyof;
var blah2 = blah.copyof();

Problem is that my implementation (more by necessity than design) is recursive, so to make the recursive calls would require assigning the method to each branch and dimension-level of the source array first (or the method could do it easily enough, but then that method WOULDN'T be leaving the source array alone, it would be modifying each of the sub-dimensions of the array). So I abandoned the OO approach and did a straight function reference approach.
 
some foot notes to my above post:
1. the line
Code:
blah["def"] = new Array();
needs to be added into the place where I am defining the dimensions of the blah array, right before the line
Code:
blah["def"]["ghi"] = 1;
(see example below)

2. remove the check in the if statement of that copyof() function for arrayObj.length > 0 because that appears to be always 0 in some cases with associative arrays (why I do not know). This test case that I have created is (of course with my luck) an example of an array with associative index'd items in it, but the .length property returns 0. figures.

3. the part where I talked about the OO approach... I just realized a dumb overlook, that WOULD actually IN THEORY allow it to work object-oriented. In this case, you define the function as part of the Array prototype, and the method is added to ALL new array objects, even those created on the fly in the recursive function, and is also thus available at each dimension level, allowing the recursive function to work.

the way to do so would be:

Code:
Array.prototype.copyof = function() {
  var temp = null;
  if (typeof this == "object") {
    temp = new Array();
    for (var index in this) {
      if (typeof this[index] == "object") {
        temp[index] = this[index].copyof();
      }
      else temp[index] = this[index];
    }
  }
  return temp;
}

var blah = new Array();
blah["abc"] = new Array();
blah["abc"]["def"] = 1;
blah["abc"]["ghi"] = 2;

blah["def"] = new Array();
blah["def"]["ghi"] = 1;
blah["def"]["jkl"] = new Array();
blah["def"]["jkl"][0] = 1;
blah["def"]["jkl"][1] = 3;


var blah2 = blah.copyof();

The only snag that I see in this approach is that each array object created with this prototype gets an element of the array with that method name as the associative index. ie, blah["copyof"] = "function () { .... };";

I think this because in my testing, I do a

Code:
for (var index in blah) {
  alert(index + "__" + blah[index]);
}
right after the definition of the blah array and its dimensions... and I get "abc", "def" and "copyof" assigned to index and alert()'d.

this is not desireable if you were trying to determine if an array was empty or not, in this case an empty array would still have the one element, the custom function. Also, this means that whatever you call the array, your array cannot have that name string as an associative index. :(

any thoughts on how to get around this would also be appreciated.
 
grammar correction:

**Also, this means that whatever you call the method, your array cannot have that method-name string as an associative index. :(**
 
I think arrays have a built in copy function:

arrayCopy = myArray.copy()
 
fugigoose is right here guys! Easiest way to do things is using the built in functions. A star to him for pointing it out.

Gary Haran
********************************
 
hate to say this, but...

i tried:

Code:
var blah2 = blah.concat(new Array());

--and--

var blah2 = blah.concat(blah,new Array());

--and--

var blah2 = Array::concat(blah,new Array());

--and--

var blah2 = blah.copy();

no go, the blah2 is an empty array on the first 2 method, and a javascript error occurs on the third method.

I get errors on the last 2 methods.

When I check MY javascript manual, there is no mention of a copy() function for the array object. But


as well as many other sites sure claim it exists. The I find out that it claims it exists because this is an extension to the Array class on that website that adds the concat() and copy() and some other methods to the array. Problem is that the copy() function uses numerical indexing, which would not allow the proper copy of an associative array.

I am using IE6 SP1, which supports (the equivalent of) javascript 1.3. how can there be no built-in way other than my method for copying an array, not just its reference?

None of the above methods have worked. :(
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top