patturik
patturik

Reputation: 135

Filter results, slow performance Swift

Swift question... I'm making a babyname app and trying to filter the results as chosen by the user. I managed to get it working, but it takes a while for the results to get filtered. I mean like 2-3 seconds.

Here is what I wrote :

func apply(list: [String]) -> [String] {
        let allSavedSettings = settings.all

        var newList = list
        
        if let short = allSavedSettings["short"] as? Bool {
            if !short {
                print("filter short")
                newList = newList.filter({$0.count > 4})
            }
        }
        if let long = allSavedSettings["long"] as? Bool {
            if !long {
                print("filter long")

                newList = newList.filter({$0.count < 5})
            }
        }
        if let dutch = allSavedSettings["dutch"] as? Bool {
            if !dutch {
                print("filter dutch")

                newList = newList.filter({!dutchboy.contains($0)})
                newList = newList.filter({!dutchgirl.contains($0)})
            }
        }
        if let english = allSavedSettings["english"] as? Bool {
            if !english {
                print("filter english")

                newList = newList.filter({!englishboy.contains($0)})
                newList = newList.filter({!englishgirl.contains($0)})
                
            }
        }
        if let arabic = allSavedSettings["arabic"] as? Bool {
            if !arabic {
                print("filter arabic")

                newList = newList.filter({!arabicboy.contains($0)})
                newList = newList.filter({!arabicgirl.contains($0)})
                
            }
        }
        if let hebrew = allSavedSettings["hebrew"] as? Bool {
            if !hebrew {
                print("filter hebrew")

                newList = newList.filter({!hebrewboy.contains($0)})
                newList = newList.filter({!hebrewgirl.contains($0)})
                
            }
        }
        if let latin = allSavedSettings["latin"] as? Bool {
            if !latin {
                print("filter latin")

                newList = newList.filter({!latinboy.contains($0)})
                newList = newList.filter({!latingirl.contains($0)})
                
            }
        }
        if let chinese = allSavedSettings["chinese"] as? Bool {
            if !chinese {
                print("filter chinese")

                newList = newList.filter({!chineseboy.contains($0)})
                newList = newList.filter({!chinesegirl.contains($0)})
                
            }
        }
        if let scandinavian = allSavedSettings["scandinavian"] as? Bool {
            if !scandinavian {
                print("filter scandinavian")

                newList = newList.filter({!scandinavianboy.contains($0)})
                newList = newList.filter({!scandinaviangirl.contains($0)})
                
            }
        }
        if let spanish = allSavedSettings["spanish"] as? Bool {
            if !spanish {
                print("filter spanish")

                newList = newList.filter({!spanishboy.contains($0)})
                newList = newList.filter({!spanishgirl.contains($0)})
                
            }
        }
        
        return newList
    }

So I save the users preferences as a Boolean value in an array called "allSavedSettings" with userdefaults. Whenever a setting is false it will filter the result from the complete list of names.

Is there something else I should use, to speed things up? The list is about 5000 names.

Thanks in advance.

Patrick

Upvotes: 0

Views: 481

Answers (1)

Rob C
Rob C

Reputation: 5073

I'd use sets wherever possible since hashing is faster than iterating over an array multiple times and it eliminates duplicates. You do not need to convert your main list to a set as that would add additional cycles.

Something like this should speed things up.

var doNotInclude = Set<String>()
        
if allSavedSettings["english"] == false {
    doNotInclude.formUnion(Set(englishBoy + englishGirl))
}

if allSavedSettings["dutch"] == false {
    doNotInclude.formUnion(Set(dutchBoy + dutchGirl))
}

if allSavedSettings["arabic"] == false {
    doNotInclude.formUnion(Set(arabicBoy + arabicGirl))
}

let result = list.filter { !doNotInclude.contains($0) }

Upvotes: 1

Related Questions