Search code examples
javascriptarraysinsertadjacenthtml

javascript: get random pairs of an array without duplicates


I have an array of students, that should be random paired by clicking the button "button-newPairs". These pairs should be shown in 8 divs "pair one", "pair two", ... that contains two spans "studentOne" and "studentTwo". I get the pairs in console but not by clicking the button "button-newPairs" and I don´t know how to change or insert the text content in my spans. Can someone help me, please? Thank you in advance.

var students = ['Al', 'Ma', 'Pu', 'Mi', 'Ma', 'Me', 'Ca', 'Na', 'Ja', 'Go', 'Ha', 'Fa', 'Ti', 'Fi' ];
var studentOne = document.querySelector('#student1');
var studentTwo = document.querySelector('#student2');


if (students.length % 2 != 0) {
  alert("You must have an even number of students. You currently have " + students.length + " students.");
} else {
  var arr1 = students.slice(), 
      arr2 = students.slice(); 

  arr1.sort(function () { return 0.5 - Math.random(); }); 
  arr2.sort(function () { return 0.5 - Math.random(); });

  while (arr1.length) {
    var student1 = arr1.pop(), 
        student2 = arr2[0] == student1 ? arr2.pop() : arr2.shift();


      $(".button-newPairs").click(function () {
        studentOne.textContent = student1;
        studentTwo.textContent = student2;      
      });
    
  
    console.log(student1 + ' works with ' + student2);
  }
}
   
.container-pairs {
  display: grid;
  grid-template-columns: 150px 150px;
  grid-gap: 20px;
  justify-content: space-around;
  align-content: center;
  margin-bottom:20px;
}

.one {
  grid-column: 1 / 2;
  grid-row: 1;
}
.two {
  grid-column: 2 / 2;
  grid-row: 1;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>

<div class="container-pairs">

        <div class="pair one">
          <span id="studentOne">NEW </span> <br>
          <span id="studentTwo"> PAIRS</span>
        </div>
        <div class="pair two">
          <span id="studentOne">NEW </span><br>
          <span id="studentTwo"> PAIRS</span>
        </div>
       
  <div id="container-footer">
          
          <div class="button-newPairs">
              <span>NEW PAIRS</span>
          </div>
  </div>

</body>


Solution

  • I've commented inline. Look for the lines with a //

    // Let's wrap this in a function so that we can call it with our button.
    function makePairs() {
    
      // We will clear our lists before each run of the function.
      $('#studentOne').html('<h1>Student 1</h1>');
      $('#studentTwo').html('<h1>Student 2</h1>');
      
      var students = ['Al', 'Ma', 'Pu', 'Mi', 'Ma', 'Me', 'Ca', 'Na', 'Ja', 'Go', 'Ha', 'Fa', 'Ti', 'Fi'];
      
      // By capturing these nodes in variables, we can reference them as our targets for insertion, below.
      var studentOne = document.querySelector('#studentOne');
      var studentTwo = document.querySelector('#studentTwo');
    
    
      if (students.length % 2 != 0) {
        alert("You must have an even number of students. You currently have " + students.length + " students.");
      } else {
        var arr1 = students.slice(),
          arr2 = students.slice();
    
        arr1.sort(function() {
          return 0.5 - Math.random();
        });
        arr2.sort(function() {
          return 0.5 - Math.random();
        });
    
        // Here we make a function that will insert a DOM fragment inside a target node
        const insertFragment = (output, target) => {
          let el;
          let fragment = document.createDocumentFragment();
          el = document.createElement('p');
          el.innerText = output
          fragment.appendChild(el);
          target.appendChild(fragment);
        }
    
        while (arr1.length) {
          var student1 = arr1.pop(),
            student2 = arr2[0] == student1 ? arr2.pop() : arr2.shift();
    
          // Here we use the function, sending student1 (the student) to studentOne (the target DOM node specified at the very top, #studentOne)
          insertFragment(student1, studentOne)
          insertFragment(student2, studentTwo)
          console.log(student1 + ' works with ' + student2);
        }
      }
    }
    
    // Run the function on load
    makePairs();
    .container-pairs {
      display: grid;
      grid-template-columns: 150px 150px;
      grid-gap: 20px;
      justify-content: space-around;
      align-content: center;
      margin-bottom: 20px;
    }
    
    .one {
      grid-column: 1 / 2;
      grid-row: 1;
    }
    
    .two {
      grid-column: 2 / 2;
      grid-row: 1;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <body>
      <div class="container-pairs">
        <div id="studentOne">
          <h1>Student 1</h1>
        </div>
        <div id="studentTwo">
          <h1>Student 2</h1>
        </div>
      </div>
      <div id="container-footer">
        <button class="button-newPairs" onclick="makePairs()">
              NEW PAIRS
            </button>
      </div>
    </body>

    The button tag, just above this line, has registered an event handler for clicks that will run the makePairs() function again.