【问题标题】:How do I avoid specific 3 element combinations using rand and split function?如何使用 rand 和 split 函数避免特定的 3 元素组合?
【发布时间】:2017-10-27 15:55:21
【问题描述】:

我有一个包含 7 个元素的变量,我需要随机选择 3 个元素,但这里是我希望避免的特定 3 个元素组合。我该如何编码? (例如,我需要它来避免组合 [2,5,7] 和 [1,3,6])

这是我目前所拥有的:

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

编辑:我想澄清一点:“数字”只是占位符,因为它们实际上是从代码的不同部分调用元素。即 1 实际上类似于“页面横幅”。所以我写的代码可以很好地选择 3 个独特的元素来填充网页,但它不允许我控制(不)显示哪个 3 个元素组合。

【问题讨论】:

  • 订单重要吗?
  • 同一个数字可以像 [3,3,3] 这样多次出现吗?
  • 不,我需要物品是独一无二的。而且我使用的数字不是数字,而是它从不同脚本调用的项目的占位符。

标签: javascript random split


【解决方案1】:

此函数将返回一个没有重复字母序列且没有排除的随机数。

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

}
// ===

【讨论】:

  • 我认为这可能是我需要的,我只是想确保我想要的代码很明显不处理数字序列(请参阅我的主帖编辑)。我基本上需要一个随机的 3 元素选择器来填充“网站”,但它排除了某些组合和重复(所以没有 3、3、3 等)。并提前感谢您的帮助!
  • @HubrisRev5 现在检查答案。我已经更新了。
  • 感谢更新,但是当我测试代码时,它不排除重复的数字(例如,227 或 661 等)。并且输出不断生成组合,因此我怀疑它不包括重复项。从技术上讲,应该只有 35 个独特的组合,减去排除的任何组合。所以重要的是,如果我告诉它排除 (2,5,7),它理解我的意思也是排除 (5,2,7; 7,5,2 等)。在此先感谢,如果我不是很清楚,很抱歉......
  • @HubrisRev5 嗨,是的,我有点困惑。立即检查。
  • 最后一个问题,当我用实际元素更改占位符数字时,我正在使用脚本挂起。我可能是使用的组合公式不理解如果一个元素不是数字“1”而是“苹果和橙子”,而不是“2”是“小狗和小猫”,将这些视为单个单元。正如我所提到的,我的代码中的数字是为了简单起见,但它们实际上反映了特定的元素。为了节省时间,我可能只是在末尾有另一个代码,将数字转换回相应的名称。
【解决方案2】:

您可以将排除集传递给函数,如果随机选择的结果与排除集匹配,则再次调用该函数

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

【讨论】:

  • 您好,感谢您的解决方案!这段代码几乎完成了我需要的一切,但有一个小问题。虽然它确实排除了“非”三元组,但它只按特定顺序工作。即 257 被忽略,但 527 或 725 不被忽略。如何更改代码以便忽略包含特定 3 个元素的所有组合?
  • 这与原始问题的描述不同
  • 您可以创建一个数组数组,其中包含所有可能的值排列,其中还包括“275”、“572”、“752”;见stackoverflow.com/q/34013675
  • var not = [[257,275,527,572,725,752],[136,163,316,361,613,631]]; return not.some(function(curr){return curr.every(function(n){+ShowRegions.join("") === n})});
【解决方案3】:

使用IndexOf() 方法从数组列表中排除特定数字。这是修改后的代码。

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;
&lt;p id="exclude"&gt;&lt;/p&gt;

【讨论】:

    猜你喜欢
    • 2016-12-25
    • 2018-11-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多