title: Swift Combine Compare String
body: <p>I have a function using Combine that provides a list of results based on user entry.</p>
  <p>For example:
  If the user types rain it will display a list of results with the word rain in it.</p>
  <p>The data is being stored in a struct and I need to first match on one element and if there are no matches, try matching on another element.</p>
  <p>For example:</p>
  <pre><code>struct dataSet: Codable, Hashable {
      let nameShort: String
      let nameLong: String
  }
  </code></pre>
  <p>When the user enters a value in the form field, I want it to first look through nameShort, and then if there are no results, look through nameLong.</p>
  <p>The second part of the equation is that I need it to match using the entire string, but with separate words.</p>
  <p>For example:
  If the user enters brown, it should look through the nameShort for brown and then the nameLong for brown. However, if there are tons of entries matching brown and the user then types brown chair, I need it to return results that match both of those values.</p>
  <p>Likewise, if the user types brow chai, it should still return brown chair as the initial characters match a word in the struct, even if nameLong is Brown - Side Chair.</p>
  <p>Here's an example of my current function:</p>
  <pre><code>func editingChangedName(_ value: String) {
      $myName
          .debounce(for: 0.3, scheduler: RunLoop.main)
          .receive(on: DispatchQueue.global()) // Perform filter on background
          .map { [weak self] filterString in
              guard filterString.count &gt;= 3, let self = self else { return [] }
              return self.nameArray.filter {
                  $0.nameShort
                      .lowercased()
                      .contains(
                          filterString.lowercased()
                      ) ||
                  $0.nameLong
                      .lowercased()
                      .contains(
                          filterString.lowercased()
                      )
              }
          }
          .receive(on: RunLoop.main) // Switch back to main thread
          .assign(to: &amp;$allNamesArray)
  } // End func
  </code></pre>
  <p>This runs onChange of the form field so it's constantly updating the results.</p>
  <p>I've tried things like:</p>
  <pre><code>let searchString = filterString.lowercased().components(separatedBy: &quot; &quot;)
  </code></pre>
  <p>below the guard statements, and then removed $0.nameShort and $0.nameLong from the return, replacing it with:</p>
  <pre><code>searchString.contains(where: $0.nameLong.contains)
  </code></pre>
  <p>but then all the results get screwy.</p>
  <p>If I remove $0.nameShort and only use $0.nameLong, and change .contains to .hasPrefix it will only read from left to right and match exactly those characters that exist. So, if I was to type chair I would get 0 results, whereas if I typed brown I would get all the results that start with brown.</p>
  <p>I feel like I'm close but can't figure out how to do this properly.</p>