¿Cómo crear un clon o copia de matriz asociativa completamente independiente en javascript, es decir, sin referencias a los valores de datos originales?

I have been trying clone the following in such a way as to avoid all referencias to the original data:

  • initially, a d3.js selection, using the clone_d3_selection() method but which, though correctly duplicating DOM elements, maintains references to selection data (the d parameter in function calls)..

  • the array at it's heart, extracted using d3's selection.data() function. Cloning seems to fail in part because the target structure appears to be a mix of object and array, but moreover because what are claimed to be clones generally maintain references to the original data, meaning changes to one are reflected in the other. A further (but minor) issue has been that (generally) null elements were being copied...

Note: JSON.parse(JSON.stringify(object)) is of no use in either case, as it applies to objects, whereas d3 uses / coerces / outputs arrays).

Applied to an array, in all respects EXCEPTO that it too replicates references, an object clone/copy function of the type shown below works fine. Despite the preserved references, it has been provided (and accepted) as a resolution to many a javascript-tagged object-cloning question.

function transfer(obj) {
    var result = [];
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            result[property.toString()] = arr[property];
        }
    }
    return result;
};

I, however, really need completa independencia from the current/original. Seems no matter what I do, references are copied.

How do I know? At regular intervals, the current selection/array is a) cloned then b) -with no further direct changes- designated previous. Beyond this point, any changes made to the clone are instantly reflected in the original - and remain through it's redesigation into previous.. The whole point of the clone was to evitar esto..

                           sole
                       modifications!
                            :
                            v
--------> current ------> clone
   ^         :
   :         v
   :      previous
   :         :
   merge.....:

Is there a better way, or might the code above be modified so that it provides a new, completely independent array, but bearing the same data values? Might this even be done directly to the original selection in a d3-centric ¿camino?

Incidentally, the array being cloned is simple enough, having been created along these lines:

var arr = [];
arr["key1"] = "value1";
arr["key2"] = 2;
 :     :      :

... followed by the accustomed d3 append() call chain.

Incidentally, every attempt at a simulation outside my rather large codebase has become mired in data formatting issues. Just astonishing what a minefield this is..

Glad of any suggestions. Thanks Thug

preguntado el 12 de junio de 14 a las 11:06

You're asking about an array, but in your sample array you're treating it like an object. Try posting a sample and write down the expected behaviour -

Yes, seems like you're completely mixing up arrays and objects. Read up on esta publicación, it is not advised to set custom array indexes like that. To produce an exact copy of an array, you could push all the properties to a new one in a for loop. Or use underscore.js _map function or the likes in other libraries. -

@Tyblitz He might need it to be recursive, in case he has nested arrays and objects -

If I'm mixing up things, it's because it took an desordenado time to find a code that would copy associative array key/value pairs in the first place but leave undefined elements behind. If there is a better alternative, I'm all ears. @thedude At this point, there is no recursion issue. -

@user1019696 Like I wrote earlier, it would help if you posted a sample. Write down the expected behavior (including excluding undefined) and show an example of how it's not working with your version. -

1 Respuestas

To deep copy an array as retrieved from a d3.js selection using selection.data():

http://www.overset.com/2007/07/11/javascript-recursive-object-copy-deep-object-copy-pass-by-value/

This link (were it more easily found) turns to be provided in other answers, making this question something of a duplicate.

The problem will be encountered more frequently as d3.js's limits are pushed, though, so rather than delete it, here it stays...

Respondido el 16 de junio de 14 a las 09:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.