0

I have been trying clone the following in such a way as to avoid all references 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 EXCEPT 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 complete independence 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 avoid this..

                           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 way?

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

Community
  • 1
  • 1
user1019696
  • 453
  • 1
  • 5
  • 15
  • 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 – thedude Jun 12 '14 at 10:18
  • Yes, seems like you're completely mixing up arrays and objects. Read up on [this post](http://stackoverflow.com/questions/1076658/javascript-array-associative-and-indexed), 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](http://underscorejs.org/#map) function or the likes in other libraries. – webketje Jun 12 '14 at 10:28
  • 1
    @Tyblitz He might need it to be recursive, in case he has nested arrays and objects – thedude Jun 12 '14 at 10:49
  • If I'm mixing up things, it's because it took an **inordinate** 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 Jun 12 '14 at 11:17
  • 1
    @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. – thedude Jun 12 '14 at 11:49
  • Json can encode arrays and objects equally well. – John Dvorak Jun 15 '14 at 12:20

1 Answers1

0

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...

user1019696
  • 453
  • 1
  • 5
  • 15