将 Switch 语句与带有嵌套枚举的结构一起使用 - Swift
Using Switch Statement with Struct with Nested Enum - Swift
带嵌套枚举结构的 Switch 语句
Swift4.1,Xcode9.3.1
我有一个非常具体的案例需要满足,但我在编写它时遇到了问题(下面有更多信息)。
***查看countHand(_:)
中的评论
我的代码:
enum Suit {
case Clubs, Diamonds, Hearts, Spades
}
enum Rank {
case Jack, Queen, King, Ace
case Num(Int)
}
struct Card {
let suit: Suit
let rank: Rank
}
extension Rank: Equatable {
static func == (lhs: Rank, rhs: Rank)
-> Bool {
switch (lhs, rhs) {
case (.Jack, .Jack), (.Queen, .Queen), (.King, .King), (.Ace, .Ace):
return true
case let (.Num(n1), .Num(n2)) where n1 == n2:
return true
default:
return false
}
}
}
extension Suit: Equatable {
static func == (lhs: Suit, rhs: Suit)
-> Bool {
switch (lhs, rhs) {
case (.Diamonds, .Diamonds), (.Hearts, .Hearts), (.Spades, .Spades), (.Clubs, .Clubs):
return true
default:
return false
}
}
}
//Main Function
func countHand(_ cards: [Card]) -> Int {
var count = 0
zip(cards, cards[1...]).forEach { card, nextCard in
let bothCards = (card, nextCard)
switch bothCards {
case let (c1, c2) where c1.rank == .Num(5) && c1.suit == .Diamonds && c2.rank == .Ace:
count += 100
case let (c1, c2) where c1.suit == .Hearts && ![.Jack, .Queen, .King, .Ace].contains(c2.rank): //I checked the contents of the array as a workaround to determine that the rank is a numeric value
//Also, if c2.rank is Rank.Num(let n) where n == 3 || n == 5 || n == 7 || n == 9
count += n * 2
default:
break
}
}
return count
}
卡片价值
卡值如下:
任何前面有 5 个方块的 A 值 100 分。
任何花色的任何奇数牌(3、5、7、9)在手牌中紧接任何红心牌时,其点数是其等级值的两倍。示例:
手牌3♥,7♣的总点数为14.
手牌3♣, 7♥的总点数为0.
要求
我想做的是 - 关于我的第二个案例陈述 - 我只想在第一张卡片 c1
和第二张卡片 c2
时调用它,满足这些标准:
c1.suit
是 .Hearts
c2.rank
是数字 (.Num(n)
) 而 n
是 3、5、7 或 9
如果这两个条件都满足,我想将 count
的值增加到 n * 2
我的问题
我进行了深入搜索,试图在网上找到一个与我的相似的案例,但不幸的是,有 none - 我可以找到 - 与我正在寻找的特异性水平相匹配为.
我试图通过做 where ... && c2.rank = .Num(let n)
之类的事情将它添加到 where
谓词中,在案例中写了一个 if
语句,只更改 [=20] 的值=] 如果它是 3、5、7 或 9,但这会产生各种错误,但我认为这不是实现它的最佳方法。这是我要解决的主要问题。如果我能做到这一点,我很确定我可以解决 where ... && ![.Jack, .Queen, .King, .Ace].contains(c2.rank)
.
提前感谢大家的所有建议、解决方案、反馈等,非常感谢您的帮助!
您不能在 where 子句中进行模式匹配,但是
您可以改为打开两张卡的两个属性:
switch (card.suit, card.rank, nextCard.suit, nextCard.rank) {
case (.Diamonds, .Num(5), _, .Ace):
count += 100
case (.Hearts, _, _, .Num(let n)) where n >= 3 && n % 2 != 0:
// Or: ... where [3, 5, 7, 9].contains(n):
count += n * 2
default:
break
}
备注:根据目前的Swift API Design Guidelines,枚举属性应该是小写的:
Names of types and protocols are UpperCamelCase
. Everything else is lowerCamelCase
.
带嵌套枚举结构的 Switch 语句
Swift4.1,Xcode9.3.1
我有一个非常具体的案例需要满足,但我在编写它时遇到了问题(下面有更多信息)。
***查看countHand(_:)
我的代码:
enum Suit {
case Clubs, Diamonds, Hearts, Spades
}
enum Rank {
case Jack, Queen, King, Ace
case Num(Int)
}
struct Card {
let suit: Suit
let rank: Rank
}
extension Rank: Equatable {
static func == (lhs: Rank, rhs: Rank)
-> Bool {
switch (lhs, rhs) {
case (.Jack, .Jack), (.Queen, .Queen), (.King, .King), (.Ace, .Ace):
return true
case let (.Num(n1), .Num(n2)) where n1 == n2:
return true
default:
return false
}
}
}
extension Suit: Equatable {
static func == (lhs: Suit, rhs: Suit)
-> Bool {
switch (lhs, rhs) {
case (.Diamonds, .Diamonds), (.Hearts, .Hearts), (.Spades, .Spades), (.Clubs, .Clubs):
return true
default:
return false
}
}
}
//Main Function
func countHand(_ cards: [Card]) -> Int {
var count = 0
zip(cards, cards[1...]).forEach { card, nextCard in
let bothCards = (card, nextCard)
switch bothCards {
case let (c1, c2) where c1.rank == .Num(5) && c1.suit == .Diamonds && c2.rank == .Ace:
count += 100
case let (c1, c2) where c1.suit == .Hearts && ![.Jack, .Queen, .King, .Ace].contains(c2.rank): //I checked the contents of the array as a workaround to determine that the rank is a numeric value
//Also, if c2.rank is Rank.Num(let n) where n == 3 || n == 5 || n == 7 || n == 9
count += n * 2
default:
break
}
}
return count
}
卡片价值
卡值如下:
任何前面有 5 个方块的 A 值 100 分。
任何花色的任何奇数牌(3、5、7、9)在手牌中紧接任何红心牌时,其点数是其等级值的两倍。示例:
手牌3♥,7♣的总点数为14.
手牌3♣, 7♥的总点数为0.
要求
我想做的是 - 关于我的第二个案例陈述 - 我只想在第一张卡片 c1
和第二张卡片 c2
时调用它,满足这些标准:
c1.suit
是.Hearts
c2.rank
是数字 (.Num(n)
) 而n
是 3、5、7 或 9
如果这两个条件都满足,我想将 count
的值增加到 n * 2
我的问题
我进行了深入搜索,试图在网上找到一个与我的相似的案例,但不幸的是,有 none - 我可以找到 - 与我正在寻找的特异性水平相匹配为.
我试图通过做 where ... && c2.rank = .Num(let n)
之类的事情将它添加到 where
谓词中,在案例中写了一个 if
语句,只更改 [=20] 的值=] 如果它是 3、5、7 或 9,但这会产生各种错误,但我认为这不是实现它的最佳方法。这是我要解决的主要问题。如果我能做到这一点,我很确定我可以解决 where ... && ![.Jack, .Queen, .King, .Ace].contains(c2.rank)
.
提前感谢大家的所有建议、解决方案、反馈等,非常感谢您的帮助!
您不能在 where 子句中进行模式匹配,但是 您可以改为打开两张卡的两个属性:
switch (card.suit, card.rank, nextCard.suit, nextCard.rank) {
case (.Diamonds, .Num(5), _, .Ace):
count += 100
case (.Hearts, _, _, .Num(let n)) where n >= 3 && n % 2 != 0:
// Or: ... where [3, 5, 7, 9].contains(n):
count += n * 2
default:
break
}
备注:根据目前的Swift API Design Guidelines,枚举属性应该是小写的:
Names of types and protocols are
UpperCamelCase
. Everything else islowerCamelCase
.