0

To search for a string included in a struct I use:

let results = myArray.filter( {$0.model.localizedCaseInsensitiveContains("bu")} )

But say the struct has several properties that I'd like to search - or maybe I'd even like to search all of them at one time. I can only filter primitive types so leaving 'model' out won't work.

Solution -------------------------

While I really liked the idea of using key paths as Matt suggested below, I ended up adding a function to my struct that made my view controller code much cleaner:

struct QuoteItem {

    var itemIdentifier: UUID
    var quoteNumber: String
    var customerName: String
    var address1: String

    func quoteItemContains(_ searchString: String) -> Bool {
        if self.address1.localizedCaseInsensitiveContains(searchString) ||
        self.customerName.localizedCaseInsensitiveContains(searchString) ||
        self.quoteNumber.localizedCaseInsensitiveContains(searchString)
        {
            return true
        }
        return false
    }

Then, in my controller, quotes is an array of QuoteItem that I can search by simply writing:

searchQuoteArray = quotes.filter({ $0.quoteItemContains(searchString) })
1

2 Answers 2

2

This sounds like a job for Swift key paths. Just supply the key paths for the String properties you want to search.

struct MyStruct {
    let manny = "Hi"
    let moe = "Hey"
    let jack = "Howdy"
}

let paths = [\MyStruct.manny, \MyStruct.moe, \MyStruct.jack]
let s = MyStruct()
let target = "y"
let results = paths.map { s[keyPath:$0].localizedCaseInsensitiveContains(target) }
// [false, true, true]
Sign up to request clarification or add additional context in comments.

Comments

2

I hope i understood you correct. I think with this piece of code you can achieve what you want:

struct ExampleStruct {
    let firstSearchString: String
    let secondSearchString: String
}

let exampleOne = ExampleStruct(firstSearchString: "Hello", secondSearchString: "Dude")
let exampleTwo = ExampleStruct(firstSearchString: "Bye", secondSearchString: "Boy")

let exampleArray = [exampleOne, exampleTwo]

let searchString = "Hello"

let filteredArray = exampleArray.filter { (example) -> Bool in

    // check here the properties you want to check
    if (example.firstSearchString.localizedCaseInsensitiveContains(searchString) || example.secondSearchString.localizedCaseInsensitiveContains(searchString)) {
        return true
    }
    return false
}

for example in filteredArray {
    print(example)
}

This prints the following in Playgrounds:

ExampleStruct(firstSearchString: "Hello", secondSearchString: "Dude")

Let me know if it helps.

1 Comment

I have ten properties in my struct that I'd like to search so I think the above example would get repetitive quickly. But I appreciate the response!

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.