0

PHP programer here struggling with Swift. How do I create a Struct (Mutidimentional array in PHP) and walk through the elements to check a value?

Here is the code I am trying but it fails:

        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
            }
        }

Error is "Value of tuple type 'Dictionary<Int, Alert>.Element' (aka '(key: Int, value: Alert)') has no member 'begin'" For a PHP guy this error message is confusing. I tried a few other things but can't seem to get the result I am looking for. I am hoping there is a simple fix or example that would work.

3
  • The error says that alrt is (key: Int, value: Alert) so you get the properties from the value: -> alrt.value.begin Commented Apr 26, 2022 at 16:31
  • The bit you may be missing in understanding the above solution from @vadian, is that with Swift when you iterate through a swift dictionary it returns the <key: value> pair as the element, not just the value. Commented Apr 26, 2022 at 16:41
  • You can learn about dictionaries in Swift here Commented Apr 26, 2022 at 17:04

2 Answers 2

2

You can enumerate each key value pair in a dictionary like so:

for (i, alrt) in alertStack

Where "i" would be your int value

But: it may be better to try to find a more Swifty way of expressing your problem (what are you trying to do?) rather than trying to translate from PHP. For example, perhaps like:

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: { $0.begin < secondsLeft }) {
    color = foundAlert.color
    alertText = foundAlert.message
}
else {
    color = "default"
    alertText = ""
}

(Maybe there is a reason but I don't know why you would want to have them in a dictionary keyed by their begin numbers)

If it helps I would imagine your problem may be expressed something like this:

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: {
        $0.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!
Sign up to request clarification or add additional context in comments.

Comments

0

You're right, that's not a big deal. Everything you need to do is write alrt.value.begin, alrt.value.color and alrt.value.message. That's because of alertStack is Dictionary<Int, Alert> (or [Int: Alert], it's the same) type. And alrt is element of Dictionary that always has key and value properties. In your case key is Int, value is Alert

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

1 Comment

This actually was a simple solution to my original problem and I was tempted to accept it as best answer. But ultimately the other answer went further to suggest a possibly better solution to my overall task. Thank you for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.