循环遍历 Struct 以检查值

Loop through Struct to check a value

PHP 程序员在这里苦苦挣扎 Swift。 如何创建结构(PHP 中的多维数组)并遍历元素以检查值?

这是我正在尝试但失败的代码:

        struct Alert: Codable {
            let begin: Double
            let end: Double
            let color: String
            let message: String
        }

        var alertStack = [ Int: Alert ]()
        
        alertStack[60] = Alert(begin: 60.0,
                               end: 55.0,
                               color: "green",
                               message: "60 Seconds" )
        alertStack[30] = Alert(begin: 30.0,
                               end: 25.0,
                               color: "yellow",
                               message: "30 Seconds!")
        
        var alrtColor = "default" // Set default
        var alrtText = "" // Set default
       
        
        for alrt in alertStack {
            if alrt.begin <= secondsLeft {
                alrtColor = alrt.color // <-- Error
                alrtText = alrt.message
            }
        }

错误是“元组类型 'Dictionary<Int, Alert>.Element' 的值(又名‘(key: Int, value: Alert)’)没有成员 'begin'” 对于一个 PHP 的人来说,这个错误消息令人困惑。我尝试了一些其他的东西,但似乎无法得到我想要的结果。我希望有一个简单的修复或示例可以工作。

您可以像这样在字典中枚举每个键值对:

for (i, alrt) in alertStack

其中“i”是您的 int 值

但是:最好尝试找到一种更快捷的方式来表达您的问题(您要做什么?),而不是尝试从 PHP 进行翻译。例如,也许像:

let alerts: [Alert] = [
    (60, 55, "green", "60 Seconds"),
    (30, 25, "yellow", "30 Seconds!")
]
.map(Alert.init(begin:end:color:message:))

let color: String
let alertText: String

if let foundAlert = alerts.last(where: { [=11=].begin < secondsLeft }) {
    color = foundAlert.color
    alertText = foundAlert.message
}
else {
    color = "default"
    alertText = ""
}

(也许是有原因的,但我不知道你为什么要将它们放在由它们的开始编号键入的字典中)

如果有帮助,我想您的问题可能会这样表达:

struct Alert: Codable {
    let color: String
    let message: String

    static let defaultAlert = Alert(color: "default", message: "")

    static let thresholds: [ClosedRange<Double>: Alert] = [
        55...60: Alert(color: "green", message: "60 Seconds"),
        25...30: Alert(color: "yellow", message: "30 Seconds!")
    ]
}

func currentAlert(value: Double) -> Alert {
    // Return the alert where the range of seconds contains
    // the provided remaining seconds value
    guard let found = Alert.thresholds.first(where: {
        [=12=].key.contains(value)
    }) else {
        return .defaultAlert
    }

    return found.value
}


print(currentAlert(value: 57)) // 60 Seconds
print(currentAlert(value: 42)) // default
print(currentAlert(value: 26)) // 30 Seconds!

你说得对,这没什么大不了的。您需要做的就是写 alrt.value.beginalrt.value.coloralrt.value.message。那是因为alertStackDictionary<Int, Alert>(或者[Int: Alert],是一样的)类型。 alrt 是 Dictionary 的元素,它始终具有 keyvalue 属性。在你的情况下 keyIntvalueAlert

for alrt in alertStack {
    if alrt.value.begin <= secondsLeft {
        alrtColor = alrt.value.color
        alrtText = alrt.value.message
    }
}