Inserting duplicate data into Javascript Array (push)

Asked

Viewed 438 times

0

I found a certain problem in a code snippet that I was developing. Suspicious that the problem could be in some other part of the project, I decided to create a smaller test environment (with another scenario) to check if the error will persist, To my surprise, it persisted.

So let’s ask the question based on this reduced scenario. In the code below I am generating two global variables agendaA and agendaB. The purpose of these variables is to store the name of all created elements, relating to each other.

Example:

  • If I generate the element To, to agendaA and the agendaB should be represented by agendaA[A] possuí [] and agendaB[A] possuí [].

  • Now if I insert a new element with the name B the representation should be: agendaA[A] possuí [B], agendaA[B] possuí [A], agendaB[A] possuí [B] and agendaB[B] possuí [A].

  • And so it should continue if I add an element C: agendaA[A] possuí [B. C], agendaA[B] possuí [A, C], agendaA[C] possuí [A. B] agendaB[A] possuí [B, C], agendaB[B] possuí [A, C] and agendaB[C] possuí [A. B].

However, once the second element is created the value of the schedules is duplicated. Instead of generating a result agendaA[A] possuí [B] it generates agendaA[A] possuí [B, B].

The most intriguing thing is that if I comment on the line agendaA[elemento_selecionado].push(id_elemento); or the line agendaB[elemento_selecionado].push(id_elemento); the application works perfectly arising another mystery - If I commented the line agendaA[elemento_selecionado].push(id_elemento); as the value is inserted in the variable agendaA?

Run the code below, enter some elements and debug the variables agendaA (console.log(scheduleA)) and agendaB (console.log(agendaB)) and see the result.

agendaA = [];
agendaB = [];

$(document).ready(function() {
  //Função de criação e registro de elementos.
  $('#inserir_elemento').click(function(){
    //Resgata o contúedo já gerado no DOM.
    var conteudo = document.getElementById('conteudo');

    //Resgato o nome do novo elemento a ser criado --- Variavel Global
    id_elemento = $('#nome').val();

    //Variavel que ira receber o nome do(s) elemento(s) já criado()s  --- Variavel Global
    elementos = [];

    //Percorre cada elemento já gerado para adicionar o nome do novo elemento na(s) respectiva(s) agenda(s).
    $('p').each(function(){
      //Recebe o nome do elemento selecionado.
      var elemento_selecionado = $(this).text();

      //Insere o nome do eleneto a ser criado na agenda do elemento selecionado pelo 'each'.
      agendaA[elemento_selecionado].push(id_elemento); //***Comente esta linha ou a debaixo e veja o resultado.
      agendaB[elemento_selecionado].push(id_elemento);

      elementos.push(elemento_selecionado);
    });

    //Cria um registro na agenda para o elemento a ser criado.
    agendaA[id_elemento] = elementos;
    agendaB[id_elemento] = elementos;

    //Cria um novo elemento.
    var novo_elemento  = document.createElement('p');

    //Insere as informações no elemento.
    novo_elemento.textContent = id_elemento;
    novo_elemento.className = id_elemento;

    //Insere o novo elemento no DOM.
    conteudo.appendChild(novo_elemento);

    //Limpa o valor do input 'nome'.
    $('#nome').val('');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<section>
  <!-- Registra um novo usuário -->
  <input id="nome" type="text" placeholder="Nome">
  <button id="inserir_elemento">Inserir</button>
</section>
<section>
  <div id="conteudo">
    <!-- Recebe o conteúdo gerado no Javascript -->
  </div>
</section>

Try to comment on the lines described in the code (One at a time) and see the result through debug.

1 answer

1


Your problem is simple, but first I want you to look at the following code snippet.:

//define um unico array vazio.
var elementos = [];

$('p').each(function(){
  //obtem o valor selecionado.
  var elemento_selecionado = $(this).text();

  //como agendaA[id_elemento] e agendaB[id_elemento] apontam para o mesmo array.
  //então o elemento é inserido duas vezes no array.
  agendaA[elemento_selecionado].push(id_elemento);
  agendaB[elemento_selecionado].push(id_elemento);

  elementos.push(elemento_selecionado);
});

//agendaA[id_elemento] e agendaB[id_elemento] apontam para o mesmo array.
agendaA[id_elemento] = elementos;
agendaB[id_elemento] = elementos;

I mean, your problem is that agendaA[n] and agendaB[n] have a reference to the same object.

Still your code could be much simpler.

agendaA = {}
agendaB = {}

var nome = document.getElementById("nome");
var inserirElemento = document.getElementById("inserir_elemento");
var removerElemento = document.getElementById("remover_elemento");
var conteudoA = document.getElementById("conteudoA");
var conteudoB = document.getElementById("conteudoB");

inserirElemento.addEventListener("click", function (event) {
  if (nome.value && !agendaA[nome.value])
  {
    var keysA = Object.keys(agendaA);
    var keysB = Object.keys(agendaB);
    keysA.forEach(function (key, indice) {
      agendaA[key].push(nome.value);
    });
    keysB.forEach(function (key, indice) {
      agendaB[key].push(nome.value);
    });
    agendaA[nome.value] = keysA;
    agendaB[nome.value] = keysB;
    
    conteudoA.textContent = JSON.stringify(agendaA);
    conteudoB.textContent = JSON.stringify(agendaB);
  }
});

removerElemento.addEventListener("click", function (event) {
  if (nome.value && agendaA[nome.value])
  {
    delete agendaA[nome.value];
    delete agendaB[nome.value];
    
    Object.keys(agendaA).forEach(function (key) {
      var elementos = agendaA[key];
      var indice = elementos.indexOf(nome.value);
      elementos.splice(indice, 1);
    });
    Object.keys(agendaB).forEach(function (key, indice) {
      var elementos = agendaB[key];
      var indice = elementos.indexOf(nome.value);
      elementos.splice(indice, 1);
    });
    
    conteudoA.textContent = JSON.stringify(agendaA);
    conteudoB.textContent = JSON.stringify(agendaB);
  }
});
<section>
  <!-- Registra um novo usuário -->
  <input id="nome" type="text" placeholder="Nome">
  <button id="inserir_elemento">Inserir</button>
  <button id="remover_elemento">Remover</button>
</section>
<section>
  <div>Agenda A: <span id="conteudoA"></span></div>
  <div>Agenda B: <span id="conteudoB"></span></div>
</section>

  • Thank you so much for your help. ; )

Browser other questions tagged

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