Secret Santa random pair allocator Please review my Secret Santa random pair allocator written in JavaScript. Random pairs will be generated every time you run the code.

Input data is hardcoded for now (line # 41).

I would love to know if you have any suggestions on improving the algorithm or any other feedback that you might have.



function getSecretSantaRandomPairs(inputArray){

  if(inputArray.length % 2 !== 0){ // array length should be even
    return;
  }

  var allocatedPairs = [], // variables for housekeeping
      randomNumber,
      randomPerson;

  while(inputArray.length !== 0){ // process the inputArray
    randomNumber = getRandomInteger(0, inputArray.length-1); // get a random number
    randomPerson = inputArray[randomNumber]; // the corresponding random person from the given list
    allocatedPairs = allocate(allocatedPairs, randomPerson); // allocate the randomPerson and update the array to be returned - allocatedPairs
    inputArray.splice(randomNumber, 1); // remove from the inputArray so that the person is not allocated again
  }

  return allocatedPairs;

}

function allocate(allocatedPairs, candidate){ // in the allocatedPairs array, mantain the pairs as objects, example: {person1: 'Peter', person2: 'Jordan'}
  // first allocate as 'person1' in the object
  if(allocatedPairs.length === 0 || (allocatedPairs[allocatedPairs.length-1].hasOwnProperty('person1') &amp;&amp; allocatedPairs[allocatedPairs.length-1].hasOwnProperty('person2') )){ // allocatedPairs is either an empty array or the object at the bottom of the allocatedPairs array had both person1 and person2
    allocatedPairs.push({person1: candidate});
  } else{ // otherwise 'person2'
    allocatedPairs[allocatedPairs.length-1].person2 = candidate;
  }

  return allocatedPairs;
}

// Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
function getRandomInteger(min, max) {
  return Math.round(Math.random() * (max - min)) + min;
}


// lets test this out

var newList = getSecretSantaRandomPairs(['John', 'Amy', 'Harry', 'Aliston', 'Jeff', 'Chris', 'Kurt', 'Jessica']);

if(newList !== undefined){
  console.log('Secret Santa Random Pairs: ', newList);

  var pairsUL = document.getElementById('pairs'),
      pairsLI,
      textLI;

  // iterate over the newList to create DOM elements 
  newList.forEach(function(currentValue, index){
    pairsLI = document.createElement('li'); // the LI element
    textLI = newList[index].person1 + ' and ' + newList[index].person2; // the text for the LI
    pairsLI.appendChild(document.createTextNode(textLI)); // add text to the LI
    pairsUL.appendChild(pairsLI); // append the LI to the UL
  });
} else {
  document.body.innerHTML = '&lt;p&gt;Please input an even number of people!&lt;p&gt;'; // source: http://stackoverflow.com/a/5419800/586051
}
&lt;ul id="pairs"&gt;&lt;/ul&gt;




Equivalent jsFiddle
As far as I remember, the game isn't strictly pairs. It's everyone's names in a hat, and everyone gets to draw a random name, redraw if it's your own name. This means you don't need an even number of names.

var pairsUL = document.getElementById('pairs'),
      pairsLI,
      textLI;

newList.forEach(function(currentValue, index){
  pairsLI = document.createElement('li'); // the LI element
  textLI = newList[index].person1 + ' and ' + newList[index].person2; // the text for the LI
  pairsLI.appendChild(document.createTextNode(textLI)); // add text to the LI
  pairsUL.appendChild(pairsLI); // append the LI to the UL
});


DOM manipulation is slow. Instead of appending to a live element on each iteration, use a fragment. It's something like an in-memory, not-in-DOM element-like container. Use document.createDocumentFragment() to create one, and append your lis to it. After the loop, append the fragment to your list.

function getRandomInteger(min, max) {
  return Math.round(Math.random() * (max - min)) + min;
}


Instead of Math.round, use Math.floor or append | 0 to the operation. Arrays are zero-indexed. Math.random values range from 0 to 1, excluding 1 itself. This means you'll never get length * 1 and floor will always round down down to the integer before length * 1, the last index in the array.

Readable code is good enough to explain what it's doing. Comments should not explain what the code already does. Instead, it should explain why it was done in that manner. Additionally, you're overloading the lines with long comments. Put them before the code described and limit them to something like 80 characters or 120 characters per line.