Inserting duplicate data in Javascript Array (push)

0

I found a particular problem in a code snippet of which I was developing. Suspicious that the problem might be elsewhere in the project, I decided to create a smaller test environment (with another scenario) to see if the error will persist, to my surprise, it persisted.

So let's get the question based on this reduced scenario. In the code below I'm generating two global variables agendaA and agendaB . The purpose of these variables is to store the name of all elements created, relating one to another.

Example:

  • If I generate the element A , the agendaA and the agendaB must 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] .

  • >

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

The most intriguing thing is that if I comment on the line agendaA[C] possuí [A. B] or the line agendaB[A] possuí [B, C] the application works perfectly creating another mystery - If I commented the line agendaB[B] possuí [A, C] how the value is being inserted in the variable agendaB[C] possuí [A. B] ?

Run the code below, insert some elements and debug the agendaA[A] possuí [B] (console.log (agendaA)) and agendaA[A] possuí [B, B] (console.log (agendaB) variables) 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><!--Registraumnovousuário--><inputid="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 also to comment the lines described in the code (one at a time) and see the result through the debug.

    
asked by anonymous 25.01.2017 / 12:12

1 answer

1

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

//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;

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

Still, your code could be a lot 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>
    
25.01.2017 / 13:41