0

Technically there are no such things as an Associative Array in Javascript. But for reasons I can't avoid, I've ended up having t do things such as

var x = [1,2,3];
x.someRequiredProperty = 'some value';

As expected, Javascript being Javascript, it works. But now, how do I make a copy of this 'array' so that I can work on multiple instances of this array without compromising the original?

I've tried jQuery $.extend([], x), which doesn't really give me a new copy. Is there something I'm missing?

Jibi Abraham
  • 4,636
  • 2
  • 31
  • 60
  • Technically there ***are*** such things as associative arrays in javascript: `{}`. – davin Jul 11 '12 at 09:16
  • @davin: technically they don't even have non-tricky ways of counting elements :-) – zerkms Jul 11 '12 at 09:20
  • and I suppose you want the array methods to work on the new object as well? – nbrooks Jul 11 '12 at 09:21
  • @zerkms, that's not usually a requirement in the definition (cf. CLRS). Not to mention that `Object.keys({...}).length` isn't all that tricky. – davin Jul 11 '12 at 09:24
  • @nbrooks - the array methods do work. And it seems I underestimated the $.extend - apparently if you deep copy the array, it works as advertised – Jibi Abraham Jul 11 '12 at 09:27
  • @jibi by new object I meant the clone you create -- I was essentially asking if it was okay to switch out to a plain javascript object, but you clarified later that you specifically need an array. if `$.extend` will work for you though then no worries – nbrooks Jul 11 '12 at 09:37
  • the best solution is here: http://stackoverflow.com/questions/565430/deep-copying-an-array-using-jquery – elhadi dp ıpɐɥןǝ Jul 18 '13 at 11:51

3 Answers3

1

I don't like the idea of an "associative" Javascript array, since adding properties to an array won't make sense to JavaScript. For instance, the length property will only count the indexed elements (not the properties), but for(var x in assoc_array) will iterate across indexes of the array as well as the "keys". So to loop just the array items you'd have to use a full for loop for(var i = 0; i < assoc_array.length; i++)....

Anyway, a copy function like this will work for your purposes:

function copy_assoc(arr)
{
    var out = [];

    for(var key in arr)
    {
        if(!arr.hasOwnProperty(key))
        {
            continue;
        }

        out[key] = arr[key];
    }

    return out;
}

Here's a demonstration of it being used: http://jsfiddle.net/DbVV8/3/

Hubro
  • 56,214
  • 69
  • 228
  • 381
0

First off, if you want an associative array you should use an object:

var x = {};
x[0] = 1;
x[1] = 2;
x[2] = 3;
x.someProperty = 'Foo';

Then if you want a copy you could use jQuery's each function to iterate over each property and build a copy:

var copy = {};
$.each(x,function(i,e){
   copy[i] = e;
});

Live example: http://jsfiddle.net/KhBC9/

Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • Thank you, but I really do need an array, Besides, why the $each? $extend is better – Jibi Abraham Jul 11 '12 at 09:28
  • You realise in JS there is pretty much no difference between an object and an array? Plus why would you use extend when you're not extending the array, just copying it? – Jamiec Jul 11 '12 at 09:30
  • There may not be much difference, but since I'm using this to plot charts with d3.js, it has to be an array. The extra properties need to be there for other sections of the code to identify sets and so on – Jibi Abraham Jul 11 '12 at 09:32
  • An array has the `length` property, among other things. It will only count the numerical indexes though – Hubro Jul 11 '12 at 09:32
0

Let me answer my own question - For all my purposes - a deep clone of the array using $.extend(true, [], myArray) gives me a new array with all my properties intact. But I like @CodeMonkey's answer.

Community
  • 1
  • 1
Jibi Abraham
  • 4,636
  • 2
  • 31
  • 60