我正在制作一个实现纸牌游戏的程序。但是,对一个卡片组(卡片数组)进行排序会产生意外的输出。
myCard.swift文件具有以下比较功能,首先按以下排序:

// For Comparable
public func <(left: Card, right: Card) -> Bool {
    if left.suit < right.suit {
        return true
    }
    return left.rank < right.rank
}

每个Card都有一个Rank和一个Suit(在Rank.swiftSuit.swift中定义),它们是具有以下比较运算符的Int枚举:
public func <(left: Rank, right: Rank) -> Bool {
    return left.rawValue < right.rawValue
}

当我做一个Euchre甲板时:
func makeEuchreDeck() {
    for suit in 1...4 {
        for rank in 9...14 {
            deck.append(Card.init(r: rank, s: suit))
        }
    }
}

然后对其进行排序(通过deck.sortInPlace()),它将给出以下输出(使用秩和西装的原始值):
9 of 1
9 of 2
9 of 3
9 of 4
10 of 1 //inconsistency here
11 of 1 //something about Clubs makes it act up
12 of 1
10 of 2 //it acts normally except for Clubs from here on
10 of 3
10 of 4
11 of 2
11 of 3
11 of 4
12 of 2
12 of 3
12 of 4
13 of 1 //back to normal here
13 of 2 //yes, including Clubs
13 of 3
13 of 4
14 of 1
14 of 2
14 of 3
14 of 4

问题
为什么和10号,杰克,和俱乐部皇后(10号,11号和12号1号)在一起表现得如此糟糕?
看起来排序函数的作用与我的预期相反。我希望它先按套装排序,然后按等级排序(就像你在一个玩把戏的游戏中通常会对手中的牌进行排序一样)。预期产出是所有的俱乐部,然后是所有的钻石等等。我的排序函数中是否有向后的内容?

最佳答案

您的比较函数不正确,应该是(例如)

public func <(left: Card, right: Card) -> Bool {

    // Compare `suit` first. If different, you are done.
    if left.suit != right.suit {
        return left.suit < right.suit
    }

    // Same `suit`, need to compare `rank`.
    return left.rank < right.rank
}

假设您希望先按suit排序,然后按rank排序。
代码中的错误是它没有正确处理案例left.rank > right.rank。在这种情况下,它应该返回false
但它实际上返回了left.rank < right.rank的结果。

10-08 02:33