4

花費數小時後,我發現無法在以下文章中由SQLite支持的NSFetchedResultsController中進行自定義排序。NSFetchedResultsController中的自定義排序

NSFetchedResultsController custom sort not getting called

但是,我找不到我的問題的實際解決方案。

這是我正在做的。

背景:
我有一個英文詞典數據庫(詞只是一個簡單的列表 - 非常大)在CoreData。單詞使用NSFetchedResultsController顯示在UITableView中。

UITableView有一個關聯的搜索欄。當用戶在搜索欄中輸入字符串時,UITableView將顯示已過濾的單詞列表。

爲什麼我需要自定義的排序:
當用戶輸入一個字符串,讓我們說這是bre,我將其更改爲正則表達式,b.*r.*e.*,並把它作爲一個NSPredicate,然後,做performFetch。因此,在表格視圖中將顯示「裸露」和「中斷」等所有單詞。

默認情況下,單詞顯示爲字母順序。因此,bare將在break之前。

我想要break在搜索列表中的bare之前,因爲break的前三個字符與用戶輸入的內容完全匹配。

可能的想法:

  1. 複製NSFetchedResultsController到的NSArray的結果,並做自定義排序。 我不確定NSArray能夠像英文字典這樣的大型數組有多快。
  2. 嘗試performFetch多次。例如上面,嘗試按順序執行bre.*,br.+e.*,b.+r.+e.*並將它們合併。

這兩個想法看起來不太整齊。

我很感激,如果你能建議任何已知的整潔的&這種問題的典型解決方案。

回答

1

您可以考慮的另一種方法是使用瞬態屬性來裝飾結果以指示匹配類型,然後使用該瞬態屬性作爲第一個排序描述符。

這需要遍歷所有結果,再次比較字符串,並設置屬性。如果你期望得到很長的一組結果,那麼使用一個數組可能會很容易。

如果您需要高效地處理大型結果集,我建議使用兩種排序描述符,一種只返回精確匹配,另一種只返回非精確匹配。然後顯示第一個結果和第二個結果。使用複合謂詞應該可以完成。

0

哇,這個問題很煩人。

我的設置如下。我有一個搜索需要輸入並通過匹配用戶名或全名查找用戶。服務器已經返回適當的順序,但由於我使用NSFetchedResultsController我需要一些排序描述符這是我做的似乎工作得很好。我添加了一個新的屬性,我的用戶的實體,稱爲matchScore並從服務器CRUD期間我得到查詢<之間的MIN() Levenshtein距離得分 - >用戶名和查詢< - >全名

我現在有一種描述符會按照用戶查詢中服務器最近的匹配結果排序。代碼是rubymotion,但應該仍然可讀。

sortDescriptors = [] 
sortDescriptors << NSSortDescriptor.sortDescriptorWithKey("matchScore", ascending:true) 

有了新的排序描述我現在可以獲取「不太理想」的結果,仍然先留着最接近的匹配。我現在可以避免@ Jaemin的一些潛在解決方案,這些解決方案涉及複雜的結果聚合,以避免自定義排序無法正常工作。

request.predicate = NSPredicate.predicateWithFormat("(username MATCHES[cd] %@) OR (username BEGINSWITH[cd] %@) OR (name CONTAINS[cd] %@)", argumentArray:[searchString, searchString, searchString]) 

現在在服務器的CRUD上生成匹配分數。

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 
}) 

這是我用來獲得Levenshtein距離的NSString類別。 https://gist.github.com/iloveitaly/1515464