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) })
squarehippo10
  • 1,855
  • 1
  • 15
  • 45

2 Answers2

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.

Teetz
  • 3,475
  • 3
  • 21
  • 34
  • 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! – squarehippo10 Jul 22 '18 at 20:54
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]
matt
  • 515,959
  • 87
  • 875
  • 1,141