Wow, this problem was annoying.
My setup is as follows. I have a search that takes input and searches for users by matching username or full name. The server has already returned the appropriate order, but since I am using NSFetchedResultsController, I need some sort descriptor. Here is what I did, it seems to work well. I added a new property to my custom object called matchScore
, and during CRUD from the server I get a score of t21> Levenshtein Distance between query β username and query β full name
Now I have a sort descriptor that will order by the closest matching results from the server with the user request. The code is Rubybotiv, but should be readable.
sortDescriptors = [] sortDescriptors << NSSortDescriptor.sortDescriptorWithKey("matchScore", ascending:true)
With the new sort descriptor, I can now get the βless than perfectβ results and still stick to the closest matches. Now I can avoid some potential @Jaemin solutions that included complex aggregation of results to get around non-standard views that don't work.
request.predicate = NSPredicate.predicateWithFormat("(username MATCHES[cd] %@) OR (username BEGINSWITH[cd] %@) OR (name CONTAINS[cd] %@)", argumentArray:[searchString, searchString, searchString])
A compliance account is now generated on the CRUD from the server.
usersContext.performBlock(lambda{ restUsers.each do |restUser| user = User.entityWithRestModel(restUser, usersContext) user.matchScore = [query.compareWithWord(user.username, matchGain:10, missingCost:1), query.compareWithWord(user.name, matchGain:10, missingCost:1].min puts "u:#{user.username} <-> q:#{query} score:#{user.matchScore}" end })
Here is the NSString
category that I use to get Levenshtein distance. https://gist.github.com/iloveitaly/1515464