我有一个enum和Struct,如下所示。
enum Position: String {
case lw = "Left Wing"
case rw = "Right Wing"
case c = "Centre"
case d = "Defense"
case g = "Goalie"
}
struct PlayerInformation {
let firstName: String
let lastName: String
let position: Position
let number: Int
}
struct ShiftDetails {
let player: PlayerInformation
var timeOnIce: Int
var dateOnIce: Date
}
我使用以下内容构建playerInformationArray
:
var playerInformationArray = [PlayerInformation]()
let sidneyCrosby = PlayerInformation.init(firstName: "Sidney", lastName: "Crosby", position: Position.c, number: 87)
let alexOvechkin = PlayerInformation.init(firstName: "Alex", lastName: "Ovechkin", position: Position.lw, number: 8)
let patrickKane = PlayerInformation.init(firstName: "Patrick", lastName: "Kane", position: Position.rw, number: 88)
playerInformationArray.append(sidneyCrosby)
playerInformationArray.append(alexOvechkin)
playerInformationArray.append(patrickKane)
我在以下数组中存储有关玩家“shift”的信息:
var shiftDetails = [ShiftDetails]()
我从集合视图中检索有关“选定”玩家的信息,其中包含以下内容:
let selectedPlayer = playerInformationArray[indexPath.row]
然后我使用以下内容更新shiftDetails
数组:
shiftDetails.append( ShiftDetails.init(player: selectedPlayer, timeOnIce: timerCounter, dateOnIce: Date()) )
一切都是例外,但我很难理解,如何从数组中检索数据。例如:
我如何检索每位玩家count
的{{1}}?
我如何检索每位玩家shiftDetails
的{{1}}?
谢谢!
答案 0 :(得分:1)
如果您需要检查某个播放器是否等于另一个播放器,您需要使其符合实现双等运算符==
的Equatable协议。您还可以使您的结构符合`CustomStringConvertible并为其提供自定义描述:
struct Player: Equatable, CustomStringConvertible {
let firstName: String
let lastName: String
let position: Position
let number: Int
static func ==(lhs: Player, rhs: Player) -> Bool {
return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName
}
var description: String {
return "Player: " + firstName + " " + lastName
}
}
同样在Swift中,您应该总是更喜欢长名称(camelCase)以获得更好的可读性,并在命名属性时尽量避免冗余信息,并且不应该将类型添加到对象名称中:
enum Position: String {
case leftWing = "Left Wing"
case rightWing = "Right Wing"
case center = "Center"
case defense = "Defense"
case golie = "Goalie"
}
struct Shift {
let player: Player
var timeOnIce: Int
var dateOnIce: Date
}
var players: [Player] = []
let sidneyCrosby = Player(firstName: "Sidney", lastName: "Crosby", position: .center, number: 87)
let alexOvechkin = Player(firstName: "Alex", lastName: "Ovechkin", position: .leftWing, number: 8)
let patrickKane = Player(firstName: "Patrick", lastName: "Kane", position: .rightWing, number: 88)
players += [sidneyCrosby, alexOvechkin, patrickKane]
var shifts: [Shift] = []
var index = IndexPath(row: 0, section: 0)
var selectedPlayer = players[index.row]
let shift1 = Shift(player: selectedPlayer, timeOnIce: 3, dateOnIce: Date())
shifts.append(shift1)
let shift2 = Shift(player: selectedPlayer, timeOnIce: 5, dateOnIce: Date())
shifts.append(shift2)
要将每个玩家的timeOnIce属性及其计数相加,您可以扩展Array将元素约束为Shift类型:
extension Array where Element == Shift {
func timeOnIceAndCount(for player: Player) -> (timeOnIce: Int, count: Int) {
return reduce((0,0)) {
$1.player == player ? ($0.0 + $1.timeOnIce, $0.1 + 1) : $0
}
}
}
let (timeOnIce, count) = shifts.timeOnIceAndCount(for: selectedPlayer)
print(selectedPlayer)
print("TimeOnIce:",timeOnIce)
print("Count: ", count)
这将打印
球员:Sidney Crosby
TimeOnIce:8
数:2
答案 1 :(得分:0)
这可能不会成为最干净的方式,因为所有的shiftDetails都保存在一个共享阵列中,但为了使用您当前的设置完成此操作,您可以使用内置的let selectedPlayer = playerInformationArray[indexPath.row]
let filteredDetails = shiftDetails.filter({ $0.player == selectedPlayer })
let shiftCount = filteredDetails.count
let timeOnIce = filteredDetails.reduce(0, { $0 + $1.timeOnIce })
用于获取有关给定玩家的信息。这看起来像这样:
filter
另一种选择是为每个玩家维护一个shiftDetails数组,此时你不需要进行任何过滤。或者,另一种选择是让shiftDetails成为一个字典,其中键是播放器,值是shiftDetails的数组。
值得注意的是,我的playerOne == playerTwo
函数示例假设您的Player结构符合Equatable协议 - 换句话说,您可以合法地说<input type="text" style="display: none" name="foo" value="original">
。如果你不这样做,你必须匹配其他一些独特的字段,如name或playerId或类似的东西。