通过 Javascript 中的 switch() 语句使用数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17818127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:44:12  来源:igfitidea点击:

Using an array through a switch() statement in Javascript

javascriptarraysswitch-statement

提问by Guilherme de Abreu

I'm trying to develop a simplified poker game through Javascript. I've listed all possible card combinations a given player might have in its hand ordered by its value, like this:

我正在尝试通过 Javascript 开发一个简化的扑克游戏。我已经列出了给定玩家可能在其手中按其价值排序的所有可能的卡牌组合,如下所示:

switch(sortedHand)
{           
 //Pair
     case [1,1,4,3,2]: sortedHand.push(1,"Pair"); break;
     case [1,1,5,3,2]: sortedHand.push(2,"Pair"); break; 
     case [1,1,5,4,2]: sortedHand.push(3,"Pair"); break;
     case [1,1,5,4,3]: sortedHand.push(4,"Pair"); break;
     case [1,1,6,3,2]: sortedHand.push(5,"Pair"); break;
     case [1,1,6,4,2]: sortedHand.push(6,"Pair"); break;
     case [1,1,6,4,3]: sortedHand.push(7,"Pair"); break;
     case [1,1,6,5,2]: sortedHand.push(8,"Pair"); break;
     case [1,1,6,5,3]: sortedHand.push(9,"Pair"); break;
     case [1,1,6,5,4]: sortedHand.push(10,"Pair"); break;

Even though the "sortedHand" array stores values succesfully (as I've seen through console.log), the switch() statement always returns the default case, and everyone gets an straight flush. I fear this is a matter of the literal approach I've used to declare possible array values to be compared with the whole of "sortedHand", but I don't know any better. Is it even possible to use switch() in such a manner?

即使“sortedHand”数组成功地存储了值(正如我通过console.log 看到的),switch() 语句总是返回默认情况,并且每个人都会得到同花顺。我担心这是我用来声明可能的数组值与整个“sortedHand”进行比较的字面方法的问题,但我不知道更好。甚至有可能以这种方式使用 switch() 吗?

回答by voithos

You can try switching on a textual representation of the array.

您可以尝试switch使用数组的文本表示。

switch(sortedHand.join(' '))
{           
    //Pair
    case '1 1 4 3 2': sortedHand.push(1,"Pair"); break;
    case '1 1 5 3 2': sortedHand.push(2,"Pair"); break; 
    case '1 1 5 4 2': sortedHand.push(3,"Pair"); break;
    case '1 1 5 4 3': sortedHand.push(4,"Pair"); break;
    // etc.
}

As an alternative to specifying every case directly, perhaps build a function dispatch table using an object and get rid of the switch entirely.

作为直接指定每种情况的替代方法,也许可以使用对象构建函数调度表并完全摆脱开关。

var dispatch = {};

// Build the table however you'd like, for your application
for (var i = 0; i < 10; i++) {
    (function(i) {
        var hand = ...; // Add your hand logic here
        dispatch[hand] = function() { sortedHand.push(i, "Pair"); };
    })(i);
}

// Execute your routine
dispatch[sortedHand.join(' ')]();

回答by Bergi

the switch() statement always returns the default case

switch() 语句总是返回默认情况

That's because the comparison doesn't check the array contents, but the array object itself. Objects are considered equal by their identity, so nothing will be equal to an object instantiated by a literal.

那是因为比较不检查数组内容,而是检查数组对象本身。对象通过它们的身份被认为是相等的,因此没有任何东西等于由文字实例化的对象。

Is it even possible to use switch() in such a manner?

甚至有可能以这种方式使用 switch() 吗?

Yes, one can use objects in switchstatements, but you would have to use references in the cases. Not applicable to your problem.

是的,您可以在switch语句中使用对象,但您必须在案例中使用引用。不适用于您的问题。

In your case, I'd suggest a stringification:

在您的情况下,我建议进行字符串化:

switch(sortedHand.join())
{           
 //Pair
     case "1,1,4,3,2": sortedHand.push(1,"Pair"); break;
     case "1,1,5,3,2": sortedHand.push(2,"Pair"); break; 
     case "1,1,5,4,2": sortedHand.push(3,"Pair"); break;
     case "1,1,5,4,3": sortedHand.push(4,"Pair"); break;
     case "1,1,6,3,2": sortedHand.push(5,"Pair"); break;
     case "1,1,6,4,2": sortedHand.push(6,"Pair"); break;
     case "1,1,6,4,3": sortedHand.push(7,"Pair"); break;
     case "1,1,6,5,2": sortedHand.push(8,"Pair"); break;
     case "1,1,6,5,3": sortedHand.push(9,"Pair"); break;
     case "1,1,6,5,4": sortedHand.push(10,"Pair"); break;

but I guess there's an even better, arithmetic solution to detect the patterns you're after. That would be shorter and faster, but I'm not sure what exactly this snippet is supposed to do.

但我想有一个更好的算术解决方案来检测你所追求的模式。那会更短更快,但我不确定这个片段到底应该做什么。

回答by dandavis

a faster, potentially reusable, and more flexible way of doing it is to use an object instead of case:

一种更快、可能可重用且更灵活的方法是使用对象而不是大小写:

var ok= {
    '1 1 4 3 2':1,
    '1 1 5 3 2':2,
    '1 1 5 4 2':3,
    '1 1 5 4 3':4
}[ sortedHand.join(' ') ] ;
if(ok){ sortedHand.push( ok ,"Pair"); }

objects work great when one output is hinged on one input. if you need to do five things in each case, then you have to use case, but if you just need X to turn into Y, (a 1:1), Look Up Tables in the shape of Objects are ideal.

当一个输出连接在一个输入上时,对象工作得很好。如果你需要在每种情况下做五件事,那么你必须使用案例,但如果你只需要 X 变成 Y,(1:1),对象形状的查找表是理想的。

i imagine a RegExp can work here, i used them on a connect4 game to identify 4 in a row, but the above logic table should work as well or better than what you describe.

我想一个 RegExp 可以在这里工作,我在 connect4 游戏中使用它们来连续识别 4 个,但上面的逻辑表应该和你描述的一样好或更好。

回答by milestyle

There are 1274 possible combinations of 5 cards in a regular deck. Listing them all out in a switch statement is completely ridiculous. Why not just have a function count any duplicates to check for 2,3,4-of-a-kinds and then check for straights? (Your array doesn't show suit so I'm assuming you are leaving it out).

普通牌组中有 1274 种可能的 5 张牌组合。在 switch 语句中将它们全部列出是完全荒谬的。为什么不让函数计算任何重复项以检查 2,3,4-of-a-kind 然后检查直线?(您的阵列不适合,所以我假设您将其排除在外)。

But if you really want to do it that way, you could use a string. Strings work with switches, and you can even use them like arrays. e.g. "123"[0] == '1'. You can change them back and forth user functions like parseInt.

但是如果你真的想那样做,你可以使用一个字符串。字符串与开关一起使用,您甚至可以像使用数组一样使用它们。例如“123”[0] == '1'。您可以像 parseInt 这样的用户函数来回更改它们。

回答by Code Whisperer

That will not quite work as you have it, but you can use sortedHand.join(',')and compare it with [1,1,1,2,5].join(',')which will compare the two arrays and should be true if their contents were the exact same (Be careful with numbers typed as strings!) To be fair, though, I can't imagine why you would design your logic like that. Even a simple card game has hundreds of thousands of possible hands. You might do better using underscore.js's collection managing functions as it will be simpler, and just a better practice.

这不会像您拥有的那样完全有效,但是您可以使用sortedHand.join(',')它并将其与[1,1,1,2,5].join(',')which 比较两个数组,如果它们的内容完全相同,则应该为真(小心number输入为 s strings!)不过,公平地说,我无法想象你为什么要这样设计你的逻辑。即使是一个简单的纸牌游戏,也有成千上万的可能手牌。使用underscore.js的集合管理功能可能会做得更好,因为它会更简单,而且是更好的实践。

回答by Martin Kersten

Since no one suggested this, use a for loop and count the number of cards with exactly the given value. Having such a function you can call 'cardCount = count(sortedHand, cardNumber)'. And of cause looping through all possible card-numbers will give you the hands.

由于没有人建议这样做,请使用 for 循环并计算具有给定值的卡片数量。有了这样一个函数,你可以调用'cardCount = count(sortedHand, cardNumber)'。当然,遍历所有可能的卡号会给你帮助。

Since a given player can only have 1x2, 2x2, 1x3, 1x3+1x2, 1x4 or straights/streets, you can return an array of all hits being arrays/objects stating the count and the cardNumber involved. So [{2, 5}, {3, 6}] for a full house.

由于给定的玩家只能有 1x2、2x2、1x3、1x3+1x2、1x4 或直道/街道,因此您可以返回所有命中的数组,这些数组是数组/对象,说明涉及的计数和卡号。所以 [{2, 5}, {3, 6}] 表示一个完整的房子。