3

I have an array structured like this and I'm trying to get a copy of it (to modify and use for React setState()). In Python I can use copy.deepcopy() but I can't find an easy way to do this in JavaScript.

notes=[
        {
          contents: "Hello World 1",
          function: console.log,
          children: [
            {
              contents: "Hello World A",
              function: console.log,
              children: []
            },
          ]
        },
        {
          contents: "Hello World 2",
          function: console.log,
          children: []
        }
      ]

I found this article and similar solutions on stackoverflow, but none of them work for me. https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d Two solutions are only a shallow copy, and JSON.parse doesn't work on functions.

I'd like to have a function that can deep copy any array or object containing any arbitrary structure of nested JavaScript datatypes.

I'd rather not reinvent the wheel writing a complex recursive function to traverse and clone everything, is there any existing solution?

3 Answers 3

5

Edit- You can use the solution below or just import Lodash and use this https://lodash.com/docs/#cloneDeep


I'm answering my own question with the solution I found. Someone posted this in the comment section of the article I linked and it seems to work

notes=[
        {
          contents: "Hello World 1",
          function: console.log,
          children: [
            {
              contents: "Hello World A",
              function: console.log,
              children: []
            },
          ]
        },
        {
          contents: "Hello World 2",
          function: console.log,
          children: []
        }
      ]

function deepCopy(src) {
  let target = Array.isArray(src) ? [] : {};
  for (let key in src) {
    let v = src[key];
    if (v) {
      if (typeof v === "object") {
        target[key] = deepCopy(v);
      } else {
        target[key] = v;
      }
    } else {
      target[key] = v;
    }
  }

  return target;
}
Sign up to request clarification or add additional context in comments.

2 Comments

See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
@hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
2

shortest way if you can not find better answer

var note2 = JSON.parse(JSON.stringify(notes))

but it didnt copy functions

so check

function iterationCopy(src) {
  let target = {};
  for (let prop in src) {
    if (src.hasOwnProperty(prop)) {
      target[prop] = src[prop];
    }
  }
  return target;
}
const source = {a:1, b:2, c:3};
const target = iterationCopy(source);
console.log(target); // {a:1, b:2, c:3}
// Check if clones it and not changing it
source.a = 'a';
console.log(source.a); // 'a'
console.log(target.a); // 1

and

function bestCopyEver(src) {
  return Object.assign({}, src);
}
const source = {a:1, b:2, c:3};
const target = bestCopyEver(source);
console.log(target); // {a:1, b:2, c:3}
// Check if clones it and not changing it
source.a = 'a';
console.log(source.a); // 'a'
console.log(target.a); // 1

from Deep copy using iteration

Comments

0

you should use for loop iterate it and judge item type, when it is object type, use recursion. the function like:

function copy(obj1, obj2) {
  var obj2=obj2||{}; 
  for(var name in obj1) {
    if(typeof obj1[name] === "object") { 
      obj2[name]= (obj1[name].constructor===Array)?[]:{}; 
      copy(obj1[name],obj2[name]);
     } else {
      obj2[name]=obj1[name]; 
   }
 }
  return obj2; 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.