Tuple
Tuple 增加了处理 n-元组的函数。
-
追加(
append(value:, toTuple:)
)或预置(prepend(value:, toTuple:)
)将创建一个给定 n-元组的副本,并添加一个额外值。 -
我们可以将 n-元组转换为数组(
arrayFromTuple(T)
)和将数组转换为 n-元组(tuple(from: [])
、triple(from: [])
等)。 -
element(at:Int, in: Tuple)
允许通过整型索引访问元组。
示例
让我们玩一场猫、老鼠和狗的游戏。这个游戏设计得很牵强。它使用了 Tuple。我们来试试
设置!
让我们创建一些玩家并洗一副扑克牌。这只是常规操作,没有用到 Tuple。
// This game of cat and mouse and dog is played with three players.
let allPlayers = (cat: "Tom", mouse: "Jerry", dog: "Pluto")
enum Suit: String, CaseIterable { case clubs; case diamonds; case hearts; case spades }
// Let's generate a shuffled array of tuples to represent our deck of cards:
var deck: [(suit: Suit, value: Int)] = Suit.allCases.flatMap {
Array(zip(Array(repeating: $0, count: 13), Array(1...13)))
}.shuffled()
来玩吧!
终于到了我们可以使用 Tuple 依赖的地方了。
// We keep track of all played cards in an array of tripples that includes the player wo drew the card:
var playedCards: [(round: Int, suit: Suit, value: Int, player: String)] = []
var round = 0
while !deck.isEmpty {
// Each round is played with only two players that are chosen at random
// First we convert the tripple of all players into an array and shuffle it:
let shuffled = Tuple.arrayFromTuple(allPlayers).shuffled()
// Now lets select two players and use a tuple to represent the players of this round:
let opponents: (firstTurn: String, secondTurn: String) = Tuple.tuple(from: Array(shuffled[0...1]))!
// We now convert the tuple of opponents into an array so we can itterate over it.
for currentPlayer in Tuple.arrayFromTuple(opponents) {
// let's pick a card and add it to our array of played cards.
let card = deck.popLast()!
// We first have to turn the card tuple into a played card triple:
let playedCard: (suit: Suit, value: Int, player: String) = Tuple.append(value: currentPlayer, toTuple: card)
// We will need to the round to calculate the final scores. Let's prepend it to the playedCard tuple. Because we can ;-)
let playedCardInRound: (round: Int, suit: Suit, value: Int, player: String) = Tuple.prepend(value: round, toTuple: playedCard)
// Now we are able to add the card to our pile of playedCards
playedCards.append(playedCardInRound)
}
round += 1
}
小结:我们使用了 arrayFromTuple(_ :)
,tuple(from: [])
,append(value:, toTuple:)
和 prepend(value:, toTuple:)
。
谁赢了?
为了精确度量,让我们使用一些更多的 Tuple 方法。
// Let's calculate scores based on the players target suit, the value of their card and the round number
func calculateValue(player: String, suit: Suit) -> Int {
return playedCards
.filter { $0.player == player }
.filter { $0.suit == suit }
.reduce(into: 0) { $0 += $1.round - $1.value }
}
let scores = (
catScore: calculateValue(player: allPlayers.cat, suit: .hearts),
mouseScore: calculateValue(player: allPlayers.mouse, suit: .diamonds),
dogScore: calculateValue(player: allPlayers.dog, suit: .clubs)
)
// We determine the actual winner by first picking one of the scores at random.
let tupleOrder = Tuple.order(of: scores)
var elementIndices: [Int] = Array(0..<tupleOrder).shuffled()
let elementIndex = elementIndices.popLast()!
let targetScore: Int = Tuple.element(at: elementIndex, in: scores)!
// If the picked score is a duplicate, everyone with the same score wins
// TODO: implement
// If the picked score is the highest score, both lower scores get a point, and if the picked score is the lowest score, both higher scores get a point
// TODO: implement
// If the picked score is in the middle, the picked score gets a point.
// TODO: implement
再次小结:我们使用了 order(of:)
和 element(at:, in:)
来计算最终的胜者。
要运行示例游乐场,请克隆仓库并打开 Example
游乐场。
要求
安装
可以通过 CocoaPods 使用 Tuple。要安装它,只需将以下行添加到您的 Podfile 中即可。
pod 'Tuple'
作者
Axel Ancona Esselmann, [email protected]
许可证
Tuple可在MIT许可证下使用。有关更多信息,请参阅LICENSE文件。