如何从数组中的Struct检索结果

时间:2017-11-30 01:01:29

标签: swift struct enums

我有一个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}}?

谢谢!

2 个答案:

答案 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或类似的东西。