cluelessCoder
cluelessCoder

Reputation: 1088

Getting contains to work with multiple words

I'm working on search and want to get it error-proof.

let's say we have 3 strings: containsText that contains 2 words I'm looking for in fullTextShort and fullTextLong

My func contains works with fullTextShort as the words that I'm looking for are right after each other, but it doesn't work with fullTextLong where there's a world in between.

How to get the func to return true for both cases?

struct ContainsFuncView: View {
    let fullTextShort = "I like pineapple"
    let fullTextLong = "I like green pineapple"
    let containsText = "like pineapple"

    var body: some View {
        VStack {
            contains(type: "Short")
            contains(type: "Long")
            }
    }
    
    func contains(type: String) -> Text {
        var containsInFullText: Bool = false
        
        if type == "Short" {
            containsInFullText = fullTextShort.localizedStandardContains(containsText)
        }
        
        else if type == "Long" {
            containsInFullText = fullTextLong.localizedStandardContains(containsText)
        }

        return Text("\(containsInFullText ? "Contains" : "Doesn't contain") in fullText\(type)").foregroundColor(containsInFullText ? .green : .red)
    }
}

Thank you!

Upvotes: 0

Views: 93

Answers (2)

Witek Bobrowski
Witek Bobrowski

Reputation: 4259

You can split the searched text into words and the reduce the search results for each word so the search returns true only when all words are found

let words = containsText.split(separator: " ")

if type == "Short" {
    containsInFullText = words.reduce(true) { contains, word in
        contains && fullTextShort.localizedStandardContains(word)
    }
}

else if type == "Long" {
    containsInFullText = words.reduce(true) { contains, word in
        contains && fullTextLong.localizedStandardContains(word)
    }
}

If you want to return true when at least one word is found, swap the && to || and the initial value to false

if type == "Short" {
    containsInFullText = words.reduce(false) { contains, word in
        contains || fullTextShort.localizedStandardContains(word)
    }
}

else if type == "Long" {
    containsInFullText = words.reduce(false) { contains, word in
        contains || fullTextLong.localizedStandardContains(word)
    }
}

Upvotes: 1

idmean
idmean

Reputation: 14885

Split containsText at the space. Then test if any or all words are in the text:

containsInFullText = containsText.components(separatedBy: " ").contains { fullTextShort.localizedStandardContains($0) }


containsInFullText = containsText.components(separatedBy: " ").allSatisfy { fullTextShort.localizedStandardContains($0) }

Upvotes: 2

Related Questions