在JavaScript中比较数组

3
我想要制作一个彩票游戏的清单,这是我的家人玩的一种类似于宾果游戏的游戏。我首先会尝试解释清单的作用和原因,抱歉我的技术英语可能不太好,我是荷兰人,所以有些词可能会错。
我有一个参加彩票/宾果游戏的人员名单。所有玩家都会选10个数字,每周会进行一次6个数字的抽奖,我会逐步解释代码需要做什么。
1 - 检查10个人的数字 2 - 每周添加6个数字,应该与人们的数字进行比较。 3 - 当匹配时,字体应该变成绿色。 4 - 当没有匹配时,字体应该保持红色。
以下是我目前拥有的代码,链接中提供了实时版本
下面的代码很好用,但问题在于代码旨在将变量A与变量B进行比较,这是瓶颈,因为这是一对一的操作。如果我想添加更多的人,就必须添加抽奖日期。
现在我的问题是:如何添加更多的人(A1、A2、A3等等),而不添加像B2这样的抽奖日期?
希望这已经足够清楚了。 :)
<script type = "text/javascript">


var a1 = ["2","3","8","12","23", "37", "41", "45", "48"]
var a2 = ["2","14","3","12","24", "37", "41", "46", "48"]

var b1 = ["2","5", "11","16","23","45", "46"];
var b2 = ["1","23", "11","14","23","42", "46"];




for (var i = 0; i< a1.length; i++) 
{
    for (var j = 0; j< b1.length; j++) 
    {
        if (a1[i] == b1[j]) 
        {
            a1[i]= "g"+ a1[i];
        }
    }
}

for (var i = 0; i< a2.length; i++)
{
    for (var j = 0; j< b2.length; j++)
    {
        if (a2[i] == b2[j]) {
            a2[i]= "g"+ a2[i];
        }
    }
}

// john
document.write("<font color = '#FFFFFF'>" + "<b>" + "John &nbsp&nbsp " + "</b>");
for (var i = 0; i< a1.length; i++) 
{
    if (a1[i].substr(0,1) == "g") 
    {
        a1[i] = a1[i].substr(1,20);
        document.write("<font color = '#00FF00'>", a1[i] + " &nbsp&nbsp ");
    }
    else
    {
        document.write("<font color = '#FF0000'>", a1[i] + " &nbsp&nbsp ");
    }
}

// Michael
document.write("<br><br>");
document.write("<font color = '#FFFFFF'>" + "<b>" + "Michael &nbsp&nbsp " + "</b>");
for (var i = 0; i< a2.length; i++) 
{
    if (a2[i].substr(0,1) == "g") 
    {
        a2[i] = a2[i].substr(1,20);

        // The Draw    
        document.write("<font color = '#00FF00'>", a2[i] + " &nbsp&nbsp ");
    }
    else
    {
        document.write("<font color = '#FF0000'>", a2[i] + " &nbsp&nbsp ");
    }
}
document.write("<br><br>");
document.write("<br><br>");
document.write("<font color = '#FFFFFF'>" + "<b>" + "Draw day 1 " + "</b>");
document.write("<br>");
document.write("<font color = '#FFFFFF'>" + "<b>" + "Sat 08-08-2009 " + "</b>");
document.write("<br><br>");
for (var j = 0; j< b1.length; j++) 
{
    document.write("<font color = '#FFFFFF'>", b1[j] + " &nbsp&nbsp ");    
}
document.write("<br><br>");
document.write("<br><br>");
document.write("<font color = '#FFFFFF'>" + "<b>" + "Draw day 2 " + "</b>");
document.write("<br>");
document.write("<font color = '#FFFFFF'>" + "<b>" + "Sat 15-08-2009 " + "</b>");
document.write("<br><br>");

for (var j = 0; j< b2.length; j++) 
{
    document.write("<font color = '#FFFFFF'>", b2[j] + " &nbsp&nbsp ");
}
</script>

@Chris:这是一个自学项目、作业还是你只是想玩一场宾果游戏? - outis
1
@所有人,我有点困惑这里的运作方式,与我通常在帮助论坛中看到的完全不同,我会先阅读FAQ :) - Chris
@Chris:如果你想快速获得100个声望值,请注册http://meta.stackoverflow.com/或http://serverfault.com/并将其与你的SO账户关联。 - outis
@ Outis,感谢你带领我穿越这片森林。我已经联系了那两个人,这些点是即时的还是需要一段时间。 - Chris
可能重复的问题 http://stackoverflow.com/questions/1296198/javascript-compare-array?rq=1 - antony.trupe
显示剩余8条评论
4个回答

4
除了像Miky D一样将数组比较重写为函数(重构),您还可以通过使用对象来保存中奖号码,使比较更加高效。请注意,这段代码不是最终版本;还有进一步的改进。
var guesses = [["2","3","8","12","23", "37", "41", "45", "48"],
               ["2","14","3","12","24", "37", "41", "46", "48"]];
var draws = [ {2:1, 5:1, 11:1, 16:1, 23:1, 45:1, 46:1},
                {1:1, 23:1, 11:1, 14:1, 23:1, 42:1, 46:1}];

function checkArray(guesses, draw) {
    for (var i = 0; i< guesses.length; ++i) {
        if (draw[guesses[i]]) {
            guesses[i] = 'g' + guesses[i];
        }
    }
}
checkArray(guesses[0], draws[1]);

将中奖号码转换为索引而不是值,可以消除循环。此外,“a”和“b”不是非常具有描述性的名称。短名称只会让代码更加晦涩难懂。
通过以不同的方式标记成功和猜测成功(当前,您在成功的前面添加“g”),您还可以简化显示结果的代码。 <font> 标签已经过时了,因此这个改进使用带有可以样式化的类的 <span>
function checkArray(guesses, draw) {
    var results = {}
    for (var i = 0; i< guesses.length; ++i) {
        if (draw.picks[guesses[i]]) {
            results[guesses[i]] = 'win';
        } else {
            results[guesses[i]] = 'loss';
        }
    }
    return results;
}
...
document.write('<span class="name">John</span>');
var results = checkArray(guesses[0], draws[1]);
for (var p in results) {
    document.write('<span class="'+results[i]+'">'+p+'</span>');
}

既然document.write也已被弃用,我将用现代的等效方式document.createElementNode.appendChild来替换它。如果你认为生成的代码过于冗长,你可以使用innerHTML, 不过它的使用是有争议的。由于选手姓名与选手选择密切相关,我还将按选手姓名对选手选择进行索引。

将以下内容放入名为“lotto.js”的文件中,该文件与网页位于同一文件夹中。

function Result(guesses) {
    for (var i = 0; i< guesses.length; ++i) {
        this[guesses[i]] = '';
    }
}
function checkDraw(guesses, draw, results) {
    for (var i = 0; i< guesses.length; ++i) {
        if (draw.picks[guesses[i]]) {
            results[guesses[i]] = 'picked';
        }
    }
    return results;
}

function appendTo(elt, parent) {
    if (parent) {
        document.getElementById(parent).appendChild(elt);
    } else {
        document.body.appendChild(elt);
    }
}

function printResults(name, results, parent) {
    var resultElt = document.createElement('div');
    resultElt.appendChild(document.createElement('span'));
    resultElt.firstChild.appendChild(document.createTextNode(name));
    resultElt.firstChild.className='name';
    var picks = document.createElement('ol');
    picks.className='picks';
    for (var p in results) {
        picks.appendChild(document.createElement('li'));
        picks.lastChild.appendChild(document.createTextNode(p));
        picks.lastChild.className = results[p];
    }
    resultElt.appendChild(picks);
    appendTo(resultElt, parent);
}

function printResultsFor(name, draws, parent) {
    var player = players[name];
    var results = new Result(player);
    for (var i=0; i<draws.length; ++i) {
        checkDraw(player, draws[i], results);
    }
    printResults(name, results, parent);
}

function printDraw(which, draw, parent) {
    var drawElt = document.createElement('div');
    drawElt.className='draw';
    drawElt.appendChild(document.createElement('h3'));
    drawElt.lastChild.appendChild(document.createTextNode('Draw '+which));
    drawElt.lastChild.className='drawNum';
    drawElt.appendChild(document.createElement('div'));
    drawElt.lastChild.className='date';
    drawElt.lastChild.appendChild(document.createTextNode(draw.when));
    var picks = document.createElement('ol');
    picks.className='picks';
    for (var p in draw.picks) {
        picks.appendChild(document.createElement('li'));
        picks.lastChild.appendChild(document.createTextNode(p));
    }
    drawElt.appendChild(picks);
    appendTo(drawElt, parent);
}

这是相应的HTML页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <style type="text/css">
      body {
        font-family: Verdana, Arial, Helvetica, sans-serif;
        color: white;
        background-color: #333;
      }
      .picks, .picks * {
        display: inline;
        margin: 0;
        padding: 0;
        list-style-type: none;
      }
      .picks * {
        margin: auto 0.25em;
      }
      #Results .picks * { color: red; }
      .name, .picks .name {
        color: white;
        font-weight: bold;
        margin-right: 0.5em;
      }
      #Results .picked { color: lime; }
      .drawNum, #Draws H3 {
          margin-bottom: 0;
      }
    </style>
    <script type="text/javascript" src="lotto.js"></script>
  </head>
  <body>
    <div id="Results"></div>
    <div id="Draws"></div>
    <script type="text/javascript">
    var players = {John:    [2,  3, 8, 12, 23, 37, 41, 45, 48],
                   Michael: [2, 14, 3, 12, 24, 37, 41, 46, 48]};

    var draws = [ {when: 'Sat 08-08-2009',
                   picks:{2:1, 5:1, 11:1, 16:1, 23:1, 45:1, 46:1}},
                  {when: 'Sat 15-08-2009',
                   picks:{1:1, 23:1, 11:1, 14:1, 23:1, 42:1, 46:1}}];

    for (name in players) {
      printResultsFor(name, draws, 'Results');
    }
    for (var i=0; i<draws.length; ++i) {
      printDraw(i+1, draws[i]);
    }
    </script>
  </body>
</html>

你可以调整CSS,以获得所需的精确样式。代码可以进一步重构以使用OOP,这将简化创建新玩家和抽奖,但涉及更多,因此我不会在此介绍。
更新:上面的代码被重写,使每个玩家的猜测与每次抽奖进行比较。该代码的实时示例版本已经进行了几乎无法识别的重构,以使用OOP。它还使用了您可能以前没有见过的功能,例如JS闭包高阶函数和CSS 生成内容和计数器。它更长,更难理解,但更灵活,稍微容易使用一些。

@Outis,感觉无聊时可以看看这个。我不太确定,但我认为我看到了一个小错误。在第一次绘制时,选择了2,但它不是绿色的,这是正常的吗?还是我错过了什么?到目前为止,你帮助很大! - Chris
@Chris:这是设计上的问题。我会检查每个玩家的猜测与当前的抽奖结果相匹配,而不是将第N个玩家与第N次抽奖结果进行比较。我仍然不确定页面是否应该玩游戏并显示结果(这是您的描述似乎在说的内容,也是我的代码所做的),还是为每个游戏显示获胜者的结果(这似乎是您原始代码尝试实现的内容)。 - outis
@outis 设计确实是检查N与抽取N,这是由codingforums的某个人制作的,这是不正确的。代码应该检查所有数字和所有抽奖,这意味着5个人可以选择“5”作为选定的数字,但可能在第3周中被命中。简而言之,所有的抽奖周应该与所有的玩家进行比较和检查(使其变成绿色),当一个数字被命中时。这不是一个游戏,只是一个我们在家里玩的检查表格。通常我们用一张纸来完成这个表格,并划掉那些数字(bingo)。它可能需要几周才能完成这个表格。 - Chris
@ Outis @ 当一个人的所有数字都被划掉(在纸上)时,他就赢得了金罐头 :D 我希望这个可以放在网站上,这样我们就不会因为狗吃了表格或者有人弄丢了而需要新的纸张。 - Chris

0

你应该使用===作为比较运算符

例如,让x = 5:

x == 8     // yield false

其中:

x == "5"   // yield **true**

=== 就像是说“完全等于”(按值类型)

x === 5    // yield true
x === "5"  // yield false

0

这里有几个我注意到的事情:

  • 你可以使用数组的数组来存储数字选择和中奖号码
  • 你可以创建一些函数来执行重复的工作
  • 你从JS渲染的HTML代码格式不正确

使用函数执行重复代码

function checkArray(myValues, winningValues)
{
   for (var i = 0; i< myValues.length; i++) 
   {
      for (var j = 0; j< winningValues.length; j++) 
      {
        if (myValues[i] == winningValues[j]) 
        {
          myValues[i] = "g"+ myValues[i];
        }
      }
   }
}

function displayNumbers(playerName, myNumbers)
{
    document.write("<font color = '#FFFFFF'>" + "<b>" + playerName + " &nbsp&nbsp " + "</b></font>");
    for (var i = 0; i< myNumbers.length; i++) 
    {
       if (myNumbers[i].substr(0,1) == "g") 
       {
          myNumbers[i] = myNumbers[i].substr(1,20);
          document.write("<font color = '#00FF00'>", myNumbers[i] + "</font> &nbsp&nbsp ");
       }
       else
       {
          document.write("<font color = '#FF0000'>", myNumbers[i] + "</font> &nbsp&nbsp ");
       }
    } 
}

// then call like this
checkArray(a1, b1);

使用数组的数组来存储您的数字和中奖号码。
var a = [["2","3","8","12","23", "37", "41", "45", "48"],
         ["2","14","3","12","24", "37", "41", "46", "48"]];

var b = [["2","5", "11","16","23","45", "46"],
         ["1","23", "11","14","23","42", "46"]];

var Players = ["John", "Michael"];

//Now you can do this:
//  for each player
for(var k = 0; k < Players.length; k++)
{
    // compare his numbers with each draw
    for(var c = 0; c < b.length; c++)
    {
       checkArray(a[k], b[c]);
       displayNumbers(Players[k], a[k]);
    }
}

添加新玩家就像轻而易举的事情一样

var a = [["2","3","8","12","23", "37", "41", "45", "48"],
         ["2","14","3","12","24", "37", "41", "46", "48"]];

var b = [["2","5", "11","16","23","45", "46"],
         ["1","23", "11","14","23","42", "46"]];

var Players = ["John", "Michael"];

//Add a new player:
Players[2] = "Adam";
a[2] = ["9","3","7","12","23", "37", "40", "45", "24"];

当然你不必同时添加人和绘图。


比较函数被定义为 checkArray,但是被调用时却使用了 checkValues(a1, b1)。你是不是想要编写一个 checkValues 函数? - outis

0

看起来非常不错,谢谢!我不确定我是否做对了,但这就是我所拥有的。 但它在FireFox中无法工作。

头部部分:

<script language="javascript">

// then call like this
checkValues(a1, b1);

var a = [["2","3","8","12","23", "37", "41", "45", "48"],
     ["2","14","3","12","24", "37", "41", "46", "48"]];

var b = [["2","5", "11","16","23","45", "46"],
     ["1","23", "11","14","23","42", "46"]];

var Players = ["John", "Michael"];

//Add a new player:
Players[2] = "Adam";
a[2] = ["9","3","7","12","23", "37", "40", "45", "24"];

function checkArray(myValues, winningValues)
{
for (var i = 0; i< myValues.length; i++) 
{
  for (var j = 0; j< winningValues.length; j++) 
  {
    if (myValues[i] == winningValues[j]) 
    {
      myValues[i] = "g"+ myValues[i];
    }
  }
}
}

 function displayNumbers(playerName, myNumbers)
{
document.write("<font color = '#FFFFFF'>" + "<b>" + playerName + " &nbsp&nbsp " + "</b></font>");
for (var i = 0; i< myNumbers.length; i++) 
{
   if (myNumbers[i].substr(0,1) == "g") 
   {
      myNumbers[i] = myNumbers[i].substr(1,20);
      document.write("<font color = '#00FF00'>", myNumbers[i] + "</font> &nbsp&nbsp ");
   }
   else
   {
      document.write("<font color = '#FF0000'>", myNumbers[i] + "</font> &nbsp&nbsp ");
    }
  } 
 }

</script>

正文部分:

<body onload="checkValues(a1, b1);">

1
更新您的实现细节应该编辑到原始问题中,而不是作为新答案。一旦您达到50个声望,您可以通过留下评论来回答其他答案以提出问题。在那之前,请将问题添加到您的原始问题中。这就是SO的结构。 - outis
@Chirs:请将调用checkValues的函数更改为“checkArray”,或更改函数名称以匹配(“checkValues”)。在我的示例中,我错误地将函数命名为checkArray,并使用checkValues进行调用。@outis指出了这一点,我已经更正了我的帖子。请参见下文并纠正您的代码。 - Mike Dinescu
1
我已经为你的问题点赞了。如果你参与并获得30个以上的积分,你就可以发表评论了。 - Mike Dinescu
我不想失礼,但我确实不知道接下来该怎么做,我尝试了你提供的代码片段,但我完全摸不着头脑,你可以再帮我一次吗?让我重新回到正确的轨道上。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接