0

I made an Array of objects named features. And then I am trying to copy in variable new_array.

   var features = mapport.panels.info.current.features();
   console.log(typeof features);
   new_array = features.slice(0);   //new_array is copy of this

And with another method as well like this

var new_array = $.map(features, function (obj) {
     return $.extend({}, obj);
     });

After this I compare new_array with a array and I delete entries which are not common So after comparison I do like

delete new_array[i].attributes.fields[f_index]

No issue is after deleting specific index values from new_array, it deleting from features as well.

How to prevent this ?

Example to demonstrate:

var features = [{
  attributes: {
    fields: ["feat1", "feat2"]
  }
}, {
  attributes: {
    fields: ["feat3", "feat4"]
  }
}]

console.log(typeof features);

// This one works!
var new_array0 = $.map(features, function(obj) {
  return $.extend(true, {}, obj); // deep clone
});
delete new_array0[1].attributes.fields[0]
document.write(JSON.stringify(new_array0)+'<br>'+JSON.stringify(features)+'<hr>')


// these make shallow copies

var new_array = features.slice(0); //new_array is copy of this
delete new_array[1].attributes.fields[0]

document.write(JSON.stringify(new_array)+'<br>'+JSON.stringify(features)+'<hr>')

var new_array1 = $.map(features, function(obj) {
  return $.extend({}, obj);
});
delete new_array1[1].attributes.fields[0]
document.write(JSON.stringify(new_array1)+'<br>'+JSON.stringify(features))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
ephemeral
  • 429
  • 2
  • 7
  • 16
  • 2
    Please click the `<>` snippet editor and create a [mcve] - My guess is you use the wrong variable. – mplungjan Jul 14 '17 at 05:09
  • 2
    `slice` will only make a shallow copy. I.e. only `delete new_array[i]` would affect only `new_array` and not `features`, anything deeper than that is shared. `delete new_array[i].attributes.fields[f_index]` deletes from `fields`, which is referenced by both `new_array` and `slice`. – Amadan Jul 14 '17 at 05:12
  • 2
    `features.slice(0)` does not do a deep copy but only a shallow copy: see [What is the difference between a deep copy and a shallow copy?](https://stackoverflow.com/questions/184710), [What is the difference between a shallow copy and a deep copy with JavaScript arrays?](https://stackoverflow.com/questions/24512712) and [How do I correctly clone a JavaScript object?](https://stackoverflow.com/questions/728360) for more details. – t.niese Jul 14 '17 at 05:13
  • 1
    You need something called "deep clone" or "deep copy", which is not natively in JavaScript. There's implementations in various libraries (e.g. lodash `cloneDeep`), or see [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript). – Amadan Jul 14 '17 at 05:16
  • You can map each property and value of each object to a new object – guest271314 Jul 14 '17 at 05:20
  • 3
    Another note: `delete new_array[i].attributes.fields[f_index]` would leave a gap in your array. It will set the entry at index `f_index` to undefined, but the length of the array is unchanged. – t.niese Jul 14 '17 at 05:25
  • @mplungjan but the OP is asking how to prevent that `attributes.fields` in `features` is modified and both examples in the fiddle, do also affect the `attributes.fields` in `features`. – t.niese Jul 14 '17 at 05:32
  • @t.niese DOH!!! Correct. What a gotcha https://jsfiddle.net/mplungjan/mqdjxgfy/ – mplungjan Jul 14 '17 at 05:37
  • What, in plain English, are you trying to do? – Asad Saeeduddin Jul 14 '17 at 05:42
  • So the answer is you are missing a true: `return $.extend(true, {}, obj); // deep clone` – mplungjan Jul 14 '17 at 05:45
  • @mplungjan my real issue is I want to delete only from new_array not from 'features' . – ephemeral Jul 14 '17 at 06:22
  • @Amadan my real issue is I want to delete only from new_array not from 'features' . – ephemeral Jul 14 '17 at 06:22
  • We understand - to do that, deep clone the object as explained – mplungjan Jul 14 '17 at 06:48
  • @mplungjan still deleting from original object :( – ephemeral Jul 16 '17 at 19:17
  • No it isn't: https://jsfiddle.net/mplungjan/8sk1fjo8/ – mplungjan Jul 16 '17 at 19:37

0 Answers0