使用带有嵌套枚举的struct的Switch语句 - Swift

时间:2018-05-26 01:00:13

标签: swift struct enums switch-statement where-clause

带有嵌套枚举的结构的开关语句

Swift 4.1,Xcode 9.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颗钻石开头的王牌都值100分。

  • 任何西装的任何奇数数字卡(3,5,7,9)都值得其等级值的两倍,当手中的任何一张牌紧接着之前。例子:

    1. 手3♥,7♣总值为14。

    2. 手3♣,7♥的总值为0。

要求

我想做的是 - 关于我的第二个案例陈述 - 如果第一张卡c1和第二张卡c2符合这些要求,我只希望它被调用标准:

  1. c1.suit.Hearts

  2. c2.rank是数字(.Num(n)),n是3,5,7或9

  3. 如果同时满足这两个标准,我想将count的值增加到n * 2

    我的问题

    我进行了深入探索,试图找到一个类似于我在线的案例,但不幸的是,没有 - 我能找到 - 与我正在寻找的特异性水平相匹配。

    我尝试将where谓词添加到where ... && c2.rank = .Num(let n)谓词中,例如if在案例中写了count语句,只更改where ... && ![.Jack, .Queen, .King, .Ace].contains(c2.rank)的值如果它是3,5,7或9,但这会产生各种错误,但我不认为这是实现它的最佳方法。这是我的主要问题,我正在询问是否要修复。如果我能做到这一点,我很确定我可以解决[lev.dtype.type for lev in index.levels]

    的解决方法

    提前感谢大家提出的所有建议,解决方案,反馈等等,我非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

你不能在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,枚举属性应为小写:

  

类型和协议的名称为UpperCamelCase。其他一切都是lowerCamelCase