Tengo una variable con 7 elementos y necesito seleccionar 3 elementos al azar, pero aquí hay combinaciones específicas de 3 elementos que quiero evitar. ¿Cómo codifico esto? (ej. lo necesito para evitar la combinación [2,5,7] y [1,3,6])

Esto es lo que tengo hasta ahora:

var Allregions = [
'1',
'2',
'3',
'4',
'5',
'6',
'7']


var ShowRegions = [];
    do {
      ShowRegions [ShowRegions.length] = Allregions.splice(
                            Math.floor(Math.random() * Allregions.length)
                          , 1)[0];
} while (ShowRegions.length < 3);

EDITAR: quería aclarar algo: los "números" son solo marcadores de posición, ya que en realidad están llamando elementos de diferentes partes del código. es decir, 1 es en realidad algo así como "banner de página". Entonces, el código que había escrito estaba bien al seleccionar 3 elementos únicos para llenar una página web, pero no me permitió controlar qué combinación de 3 elementos se muestra (no).

3
HubrisRev5 27 oct. 2017 a las 18:55

3 respuestas

La mejor respuesta

Esta función devolverá un número aleatorio sin secuencia de letras repetidas y sin exclusiones.

var allRegions = ['1', '2', '3', '4', '5', '6', '7'];

// to skip sequence of repeated letters.
var isSequence = /^([a-zA-Z0-9])\1+$/;
// to skip, if the combination has duplicates.
var hasDuplicates = /([a-zA-Z0-9]).*?\1/;

function isNotUniqueCombination(ex, rand) {
  for (var n = 0; n < ex.length; n++) {
    var e = ex[n];
    var combinations = [
      [e[0], e[1], e[2]],
      [e[0], e[2], e[1]],
      [e[1], e[0], e[2]],
      [e[1], e[2], e[0]],
      [e[2], e[0], e[1]],
      [e[2], e[1], e[0]]
    ];
    for (var i = 0; i < combinations.length; i++) {
      var com = combinations[i];
      if (com.join("") === rand.join("")) return true;
    }
  }
  return false;
}

/**
 * Return a random number without sequence of repeated letters & without excludes
 * @param {String} array 
 * @param {String} excludes 
 */
function getRandom(array, excludes) {

  // Random number array
  var randomNumber = [];

  var excludesMap = excludes.map(function(e) {
    return e.join("");
  });

  do {
    // Generate random number
    randomNumber = [
      array[Math.floor(Math.random() * array.length)],
      array[Math.floor(Math.random() * array.length)],
      array[Math.floor(Math.random() * array.length)]
    ];

  } while (excludesMap.indexOf(randomNumber.join("")) !== -1 || isSequence.test(randomNumber.join("")) || hasDuplicates.test(randomNumber.join("")) || isNotUniqueCombination(excludes, randomNumber));

  return randomNumber;
}

var excludes = [
  ['2', '5', '7'],
  ['1', '3', '6']
];


// Test Case
// =========
for (var i = 0; i < 1e3; i++) {
  var arr = getRandom(allRegions, excludes);

  var div = document.createElement('div');
  div.innerHTML = arr.join("");
  document.body.appendChild(div);

  // Check if the string contains a sequence of repeated letters of has duplicates
  if (isSequence.test(arr.join("")) || hasDuplicates.test(arr.join("")) || isNotUniqueCombination(excludes, arr)) {
    div.style.color = "#ff0000";
    div.innerHTML += " [ sequence of repeated letters found || duplicates found ]";
    document.body.appendChild(div);
    break;
  }

}
// ===
1
dinindu 30 oct. 2017 a las 16:16

Utilice IndexOf () Método para excluir el número paticular de la lista de la matriz. Aquí está el código modificado.

var Allregions = ['1','2','3','4','5','6','7'];

var ShowRegions = [];
randomNot(); // call the function to generate the number

function randomNot(){
  do {
    ShowRegions [ShowRegions.length] = Allregions.splice(Math.floor(Math.random() * Allregions.length), 1)[0];
  }
  while (ShowRegions.length < 3);
}
console.log("Response: "+ShowRegions);
var excludeNo = new Array("2,5,7", "1,3,6");

if(excludeNo.indexOf(ShowRegions) != -1){  
    console.log("Excluded Number");
    randomNot();
}
document.getElementById("exclude").innerHTML = ShowRegions;
<p id="exclude"></p>
0
vasanth 30 oct. 2017 a las 10:44

Puede pasar los conjuntos excluidos a una función, si el resultado de la selección aleatoria coincide con un conjunto excluido, vuelva a llamar a la función

var Allregions = ["1","2","3","4","5","6","7"];

function randomNot(arr, not) {
  var curr = arr.slice();
  var ShowRegions = [];
  do {
    ShowRegions[ShowRegions.length] = curr.splice(
      Math.floor(Math.random() * curr.length), 1)[0];
  } while (ShowRegions.length < 3);
  return not.some(function(n) {
    return n === ShowRegions.join("")
  }) ? randomNot(arr, not) : ShowRegions
}

var not = ["257", "136"];

var res = randomNot(Allregions, not);

console.log(res);
1
guest271314 27 oct. 2017 a las 16:04