0

I have to manipulate a nested object. Here's my code:

function modify(object) {
  Object.keys(object).forEach(key => {
    if (typeof object[key] === 'object') {
      if (object[key].class && object[key].type && object[key].period) {
        object[key].applicableName = `${object[key].class}|${object[key].type}|${object[key].period}`;
        delete object[key].class;
        delete object[key].type;
        delete object[key].period;
      } else {
        modify(object[key]);
      }
    }
  });
}

Here's the object:

[
    {
        "item": [
            {
                "period": "period-CYTM",
                "type": "type-CMLT",
                "class": "class-RFEE",
            },
            {
                "period": "period-FYTD",
                "type": "type-CMLT",
                "class": "class-RFEE",
            },
            {
                "period": "period-ITD",
                "type": "type-ANNL",
                "class": "class-RFEE",
            },
            {
                "period": "period-ITD",
                "type": "type-CMLT",
                "class": "class-RFEE",
            },
            {
                "period": "period-1MTH",
                "type": "type-CMLT",
                "class": "class-RFEE",
            },
            {
                "period": "period-1YR",
                "type": "type-CMLT",
                "class": "class-RFEE",
            },
            {
                "period": "period-10YR",
                "type": "type-ANNL",
                "class": "class-RFEE",
            },
            {
                "period": "period-10YR",
                "type": "type-CMLT",
                "class": "class-RFEE",
            }
        ]
    }
]

It is working fine, but the issue is that it is mutating the original object. How can I make my modify method return a new modified object and the original object remains intact?

I tried to clone the original object and then passed the cloned object to the modify method, but, that was not an elegant solution in my opinion.

Pritam Bohra
  • 3,912
  • 8
  • 41
  • 72
  • Possible duplicate of [Modifying a copy of a JavaScript object is causing the original object to change](https://stackoverflow.com/questions/29050004/modifying-a-copy-of-a-javascript-object-is-causing-the-original-object-to-change) – Julian W. Jun 19 '19 at 03:42
  • what about `return object;` after the loop? – Junius L Jun 19 '19 at 03:42

2 Answers2

0

How about just making a copy on the fly in your function?

function modify(object) {
  const copy = {};
  Object.keys(object).forEach(key => {
    if (typeof object[key] === 'object') {
      if (object[key].class && object[key].type && object[key].period) {
        copy[key].applicableName = `${object[key].class}|${object[key].type}|${object[key].period}`;
      } else {
        copy[key] = modify(object[key]);
      }
    } else {
      copy[key] = object[key];
    }
  });
  return copy;
}
Grant
  • 442
  • 5
  • 19
0

I tried to clone the original object and then passed the cloned object to the modify method, but, that was not an elegant solution in my opinion.

Why? You don't want to modify your original object and the object cloning is the best practice in this situation.

You can do cloning inside your function too.

function modify(object) {

  //cloning object
  var copyObject = object.constructor();

  Object.keys(copyObject ).forEach(key => {
    if (typeof copyObject[key] === 'object') {
        //...
    }
  });

  return copyObject;

}
Masoud Keshavarz
  • 2,166
  • 9
  • 36
  • 48