0

I have created an array struct to house my values used in a list. Now I want to be able to search this list and every time the user makes a blank space it should be viewed by the program as two different searchwords that should both be met. I have successfully created a function to get the searchwords but I don't really get how to now filter my stuctArray by all the searchWords.

let searchWords = findAllSearchResutsRecursive(searchWord) //example ["A", "B", ,"C"]

let filteredArray = listArray.filter {
    for word in searchWords {
        $0.firstname!.capitalized.contains(word.capitalized) ||
        $0.lastname!.capitalized.contains(word.capitalized) ||
        $0.id!.capitalized.contains(word.capitalized) ||
        $0.city!.capitalized.contains(word.capitalized)
    }
}

To clarify, if the searchWords is ["A", "N"] and one of the participants (people in the list) has the firstname "Anna" but nothing else match the search I still want to show it.

Alternatively is if it would be better to convert the SearchWords to a set and in that way somehow filter them all at the same time.

This is errors I get: enter image description here

5
  • So what is wrong with your code? What error do you get? What does not work? Commented Jan 18, 2023 at 16:05
  • @burnsi I updated the question with a screenshot so you can see my errors Commented Jan 18, 2023 at 16:08
  • 1
    The closure to filter needs to return a boolean for each element being filtered. Your code has a for loop inside the filter. The body of a for loop cannot not return a boolean. You will need to refactor your code. Commented Jan 18, 2023 at 16:23
  • I believe contains() will match strings of letters in the middle of a word. So if your search "word" is "a" it will match the first name "Pat" as well as "Alan" Similarly, a search string of "Pat" would match the name "Patterson". – Commented Jan 18, 2023 at 18:01
  • This seems like an odd way to search. If you want to find records with a last name value of "York", you would also match people who live in a city named "York". Shouldn't you have specific search strings for each field instead? Commented Jan 18, 2023 at 18:04

2 Answers 2

1

You could rewrite it like this:

let searchWords = findAllSearchResutsRecursive(searchWord) //example ["A", "B", ,"C"]

let filteredArray = listArray.filter {
    var matchFound = false
    for word in searchWords {
        if (
          $0.firstname!.capitalized.contains(word.capitalized) ||
          $0.lastname!.capitalized.contains(word.capitalized) ||
          $0.id!.capitalized.contains(word.capitalized) ||
          $0.city!.capitalized.contains(word.capitalized)
        ) {
            matchFound = true
          }
    }
    return matchFound
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks this solution worked almost as I wanted it to. The only problem is when I now search for a name and a city it shows both all with that name and all people with that city. What I want is to only show results that match both.
So if the search word is "A" you'd only want to select records for people named Alan who live In Albany, but not Betty who lives in Albany? That's odd.
1

The outer filter function needs to return a boolean value. To not iterate over all remaining words if a match is found you could use:

let filteredArray = listArray.filter {
    var result = false
    for word in searchWords {
        
        // check if any property contains the word
        if $0.firstname!.capitalized.contains(word.capitalized) ||
        $0.lastname!.capitalized.contains(word.capitalized) ||
        $0.id!.capitalized.contains(word.capitalized) ||
            $0.city!.capitalized.contains(word.capitalized){
            // set the result and break the loop
            result = true
            break
        }
    }
    // return the result
    return result
}

Comments

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.