首页 > 解决方案 > 通过匹配对 Realm 中的过滤结果进行排序

问题描述

我有一个包含约 100k 条目的字典,并提供了一个搜索功能,用户可以在其中搜索英文/中文字符串,并且将显示包含该字符串的所有条目。条目具有以下结构:

class DictionaryEntry: Object, Identifiable {
    @objc dynamic var id: String = NSUUID().uuidString
    @objc dynamic var character: String = ""
    @objc dynamic var pinyin: String = ""
    @objc dynamic var definition: String = ""
}

假设我们有以下两个条目:

entry1 = "宝山 / Bǎoshān / Bǎoshān district of Shanghai" 
entry2 = "上海 / Shànghǎi / Shanghai" 

搜索字符串为“shanghai”。我通过这种方式过滤条目:

let realm = try! Realm()
realm.objects(DictionaryEntry.self)
     .filter("pinyin CONTAINS[cd] %@ OR definition CONTAINS[cd] %@ OR character CONTAINS[cd] %@", searchString, searchString, searchString)
   //.sorted(by: ???)

由于两个条目都包含搜索字符串,因此两个条目都会出现,但它们尚未按任何逻辑排序。我想按最高的“覆盖/匹配”对结果进行排序。所以首先应该出现“上海”,然后出现“上海大学”,......,最后出现“苏州和上海之间的旧运河”这样的条目。有没有内置的领域解决方案?

标签: swiftrealm

解决方案


RealmResults有内置的排序方法,请参阅文档中的排序

如果要根据特定属性进行排序,可以使用sorted(byKeyPath:)which 接受一个String表示要排序的属性名称:

let realm = try! Realm()
realm.objects(DictionaryEntry.self)
   .filter("pinyin CONTAINS[cd] %@ OR definition CONTAINS[cd] %@ OR character CONTAINS[cd] %@", searchString, searchString, searchString)
   .sorted(byKeyPath: "pinyin")

或者,如果您想根据您过滤的所有 3 个属性进行排序,您可以使用sorted(by:),它接受一个对象,Sequence这些SortDescriptor对象也可以基于键路径创建:

let realm = try! Realm()
realm.objects(DictionaryEntry.self)
   .filter("pinyin CONTAINS[cd] %@ OR definition CONTAINS[cd] %@ OR character CONTAINS[cd] %@", searchString, searchString, searchString)
   .sorted(by: [SortDescriptor(keyPath: "pinyin"), SortDescriptor(keyPath: "definition"), SortDescriptor(keyPath: "character")])

推荐阅读