Delete copied array item without deleting the item from its source - Vuejs

Asked

Viewed 147 times

1

I would like to clone a list of numbers and be able to manipulate that cloned list without changing the source, but in the following situation when I delete the item from the cloned array it deletes the source.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
  <div id="app">
    <ul>
      <h3>Lista Origem</h3>
      <li v-for="item in listaOriginal">
        {{item}}
      </li>
    </ul>

    <ul>
      <h3>Lista Clone</h3>
      <li v-for="item in listaClone">
        {{item}}
      </li>
    </ul>

    <button @click="clonaLista">Clonar Lista</button>
    <button @click="removerItem">Remover item do Clone</button>
  </div>

  <script>
    const vue = new Vue({
      el: "#app",
      data: {
        listaOriginal: [1, 2, 3],
        listaClone: []
      },

      methods: {
        clonaLista() {
          this.listaClone = this.listaOriginal
        },

        removerItem() {
          this.listaClone.pop()
        }
      }
    })
  </script>
</body>

</html>

3 answers

1


Rodolfo this is because the Array is a referenced type (Reference type). When you say that listaClone = listaOriginal both variables point to the same array. To solve use a spread to clone effectively:

this.listaClone = [...this.listaOriginal];

1

There are several ways to copy an array, but you need to know if you want a shallow copy (Shallow copy) or a deep copy (deep copy) 1.

If you’re just working with primitive types like Number, String or Boolean It won’t make a difference if you use a shallow or deep copy. From the moment your array contains other arrays or objects, you will be working with references, if you just copy those references you will be making a shallow copy, but if you make a copy of the object for the new array, you will be making a deep copy.

let array = [1, 2, 3, 4];
let copia = array;  // cópia da referência

copia.push(5);

// Como `array` e `copia` referenciam o mesmo
// objeto em memória, alterações feitas em 
// ambos inferem no mesmo objeto
console.log(array);
// [1, 2, 3, 4, 5]


Some methods to create hard copies (Shallow Copy)

  1. Array.slice (#Docs & compatibility)

    David Walsh posted in this article a way to make a shallow copy using the method Array.slice. The great advantage of this method is its compatibility with older browsers.

    let array = [1, 2, 3];
    let copia = array.slice(0);
    
    copia.push(4);
    
    console.log(array);  // [1, 2, 3]
    console.log(copia);  // [1, 2, 3, 4]
    
  2. Spread Operator (#Docs & compatibility)

    let array = [1, 2, 3];
    let copia = [...array];
    
  3. For loop

    let array = [1, 2, 3];
    let copia = [];
    
    for (let i=0, l=array.length ; i<l ; i++) {
        copia.push(array[i]);
    }
    
  4. Array.map (#Docs & compatibility)

    let array = [1, 2, 3];
    let copia = array.map(x => x);
    

Methods to create deep copies (Deep copy)

  1. JSON.stringify and JSON.parse (compatibility)

    You can use JSON.stringify and JSON.parse to create deep copies of objects.

    let array = [[1], [2], [3]];
    let copia = JSON.parse(JSON.stringify(array));
    
    copia[0].push(1.5);
    
    console.log(array); // [[1], [2], [3]]
    console.log(copia); // [[1, 1.5], [2], [3]]
    
  2. _.cloneDeep (#Docs)

    If you are using the lodash library, you can use the function _.cloneDeep.

    let array = [[1], [2], [3]];
    let copia = _.cloneDeep(array);
    
    copia[0].push(1.5);
    
    console.log(array); // [[1], [2], [3]]
    console.log(copia); // [[1, 1.5], [2], [3]]
    

This article mentions some other methods you can use to create shallow copies.

0

You can get a copy of the array by doing so:

let array = [1, 2, 3];
let copy  = array.slice()

The way you did was not copying the array, but referencing it. :)

  • That way has already been mentioned in my reply. What it does different from what I mentioned?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.