我的循环并不总是命中最后几个数组项目,并且偶尔会失败我的一个条件



这是我正在制作的一个小程序,用于生成我朋友的秘密圣诞老人名字。当我收到每个人的电子邮件时,我将创建一个数组,并在循环中向当前人员(从我的电子邮件)发送一封包含消息的电子邮件。

目前,我将其写入HTML页面以获取结果。有时它不会经历循环的所有步骤(会跳过最后几个人),有时它会破坏我的一个 if 语句,并允许我不想要的匹配。

这是一个简单的程序,我不想想太多,但显然我第一次尝试它不起作用。谁能提出更可靠的方法来做到这一点?我正在考虑一个 while 循环,如果它返回不需要的匹配,则计算结果为 false。

var names = [
  "Jessica",
  "William",
  "Justine",
  "Max",
  "Funke",
  "Zach",
  "Emery",
  "Autumn",
  "Ethan",
  "Rhnea",
  "Richard",
  "Laura Bane",
  "Toran",
  "Carla",
  "Matt",
  "Joe",
  "Andy",
  "Evan",
  "Pat"
];
var names2 = [
  "Jessica",
  "William",
  "Justine",
  "Max",
  "Funke",
  "Zach",
  "Emery",
  "Autumn",
  "Ethan",
  "Rhnea",
  "Richard",
  "Laura Bane",
  "Toran",
  "Carla",
  "Matt",
  "Joe",
  "Andy",
  "Evan",
  "Pat"
];
var emails = [];
var message = "";
var generateMatch = function() {
  var match = Math.floor(Math.random() * names2.length);
  if (names[i] != names2[match]) {
    if (names2[match] == undefined) {
      generateMatch();
    }
    if (names[i] == "Jessica" && names2[match] == "William") {
      generateMatch();
    }
    if (names[i] == "Jessica" && names2[match] == "Evan") {
      generateMatch();
    }
    if (names[i] == "William" && names2[match] == "Jessica") {
      generateMatch();
    }
    if (names[i] == "William" && names2[match] == "Evan") {
      generateMatch();
    }
    if (names[i] == "Justine" && names2[match] == "Max") {
      generateMatch();
    }
    if (names[i] == "Max" && names2[match] == "Justine") {
      generateMatch();
    }
    if (names[i] == "Funke" && names2[match] == "Zach") {
      generateMatch();
    }
    if (names[i] == "Zach" && names2[match] == "Funke") {
      generateMatch();
    }
    if (names[i] == "Emery" && names2[match] == "Autumn") {
      generateMatch();
    }
    if (names[i] == "Autumn" && names2[match] == "Justine") {
      generateMatch();
    }
    if (names[i] == "Ethan" && names2[match] == "Rhnea") {
      generateMatch();
    }
    if (names[i] == "Rhnea" && names2[match] == "Ethan") {
      generateMatch();
    }
    if (names[i] == "Richard" && names2[match] == "Laura Bane") {
      generateMatch();
    }
    if (names[i] == "Laura Bane" && names2[match] == "Richard") {
      generateMatch();
    }
    if (names[i] == "Toran" && names2[match] == "Carla") {
      generateMatch();
    }
    if (names[i] == "Carla" && names2[match] == "Toran") {
      generateMatch();
    } else {
      message = "Hello " + names[i] + ", your match is " + names2[match] + "<br>";
      names2.splice(match, 1);
    }
  } else {
    generateMatch();
  }
}
var length = names.length + 1;
for (var i = 0; i < length; i++) {
  generateMatch();
  document.write(message);
  //window.open('mailto:' + email[i] + '?subject=Brozmas&body=' + message);
}

此问题可能不是递归的最佳用途。从我对你的代码的粗略阅读中,你想随机匹配两个名称,并有一些内置的异常。你可以用while循环做这样的事情。

while (names.length > 0)
    pick names from names and names2
    if the pair of names is a built-in exception:
        continue
    output the matching name pair
    pop the names from names and names2

只要names数组中有人,此循环就会运行。这保证了names数组中的每个人都将有一个秘密圣诞老人匹配。 continue意味着如果名称对是内置异常之一,则循环将跳过执行,并且从数组中弹出名称表明存在匹配项。

附言最好为数组(如 fromto)使用更具描述性的名称。

编辑:我重新阅读了您的原始帖子,现在我看到了这个问题。使用您选择的不匹配规则,无法生成足够多的适当匹配以使其成功并生成无限循环。如果我添加一个"tryes"标志来阻止它永远循环并检查我们尝试找到匹配项的次数,由于规则,我们每次都会留下大约 50% 的名称不匹配。还有人想插话吗?

我在仍然使用递归的同时清理了您的代码。这将生成一个 from-to 数组,您可以对其进行扩展以生成发送给所有配对个人的电子邮件。

var names = [
 		{name:"Jessica", email: "", match: null, noMatch: ['William', 'Evan'], tries:0},
    {name:"William", email: "", match: null, noMatch: ['Jessica', 'Evan'], tries:0},
    {name:"Justine", email: "", match: null, noMatch: ['Max'], tries:0},
    {name:"Max", email: "", match: null, noMatch: ['Justine'], tries:0},
    {name:"Funke", email: "", match: null, noMatch: ['Zach'], tries:0},
    {name:"Zach", email: "", match: null, noMatch: ['Funke'], tries:0},
    {name:"Emery", email: "", match: null, noMatch: ['Autumn'], tries:0},
    {name:"Autumn", email: "", match: null, noMatch: ['Emery', 'Justine'], tries:0},
    {name:"Ethan", email: "", match: null, noMatch: ['Rhnea'], tries:0},
    {name:"Rhnea", email: "", match: null, noMatch: ['Ethan'], tries:0},
    {name:"Laura Bane", email: "", match: null, noMatch: ['Richard'], tries:0},
    {name: "Richard", email: "", match: null, noMatch: ['Laura Bane'], tries:0},
    {name:"Toran", email: "", match: null, noMatch: ['Calra'], tries:0},
    {name:"Carla", email: "", match: null, noMatch: ['Toran'], tries:0},
    {name:"Matt", email: "", match: null, noMatch: [], tries:0},
    {name:"Joe", email: "", match: null, noMatch: [], tries:0},
    {name:"Andy", email: "", match: null, noMatch: [], tries:0},
    {name:"Evan", email: "", match: null, noMatch: [], tries:0},
    {name:"Pat", email: "", match: null, noMatch: [], tries:0},
    {name: "No Match Found", email: "NoMatch@NoMatch.com", match: 99, noMatch: [], tries:0} 
];
let generatedEmails = [];
function assignMatch(arr, i) {
	if(arr.tries == 2) arr.match = names.length-1;
	if(arr.match === null || arr.tries < 2) {
		let randomIndex = (Math.floor(Math.random() * names.length));
  	if(names[randomIndex].match != null || randomIndex === i || arr.noMatch.contains(names[randomIndex].name)){
    	arr.tries++;
    	assignMatch(arr, i);
    } else {
    	arr.match = randomIndex;
      names[randomIndex].match = i;
    }
  }
}
Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] == obj) {
            return true;
        }
    }
    return false;
}
function generateEmails(arr, i) {
	if(arr.name != "No Match Found" || names[arr.match].name != "No Match Found"){ 
    let content = {
      fromName: arr.name,
      fromEmail: arr.email,
      toName: names[arr.match].name,
      toEmail: names[arr.match].email
    };
    generatedEmails.push(content);
   }
}
names.forEach((arr, i) => assignMatch(arr, i));
names.forEach((arr, i) => generateEmails(arr, i));
console.table(generatedEmails);

希望这有所帮助。不要犹豫,提出问题。

最新更新