samir samir - 5 months ago 24
Swift Question

Using pattern matching to filter array

this is my code:

enum SymptomPeriod {
case Day
case Night
}

enum SymptomType {

case Breathing(SymptomPeriod)
case Breathlessness(SymptomPeriod)
case Opression(SymptomPeriod)
case Cough(SymptomPeriod)

case ActivityLimited()
case SecureTreatment()
}

struct Symptom {
let type: SymptomType
let date: NSDate
}


And i have an array of symptoms.

let symptomList: [Symptom] = ...


My need is to filter the list of symptoms with the SymptomPerion criteria, i trying to do like this:

let daySymtoms = symptomList.filter { (symptom) -> Bool in
return symptom.type = ???
}


My problem is in the filter function.

(My goal is to use a filter function and not a loop)

Answer

A few suggestions

Use your struct as namespace

Instead of repeating the word Symptom (e.g. SymptomPeriod, SymptomType) you should put your enums into you Symptom struct

Rename SymptomType as Kind

Once you moved SymptomType into Symptom you can drop the Symptom part of the name. However using Type as name will create a conflict so you should rename it Kind.

Add the period computed property to Kind

This will make the filtering much easier

Here's the code

struct Symptom {
    enum Period {
        case Day
        case Night
    }

    enum Kind {
        case Breathing(Period)
        case Breathlessness(Period)
        case Opression(Period)
        case Cough(Period)

        case ActivityLimited()
        case SecureTreatment()

        var period: Period? {
            switch self {
            case Breathing(let period): return period
            case Breathlessness(let period): return period
            case Opression(let period): return period
            case Cough(let period): return period
            default: return nil
            }
        }
    }

    let kind: Kind
    let date: NSDate
}

The solution

Now the filtering has become very easy

let symptoms: [Symptom] = ...
let filtered = symptoms.filter { $0.kind.period == .Day }