Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
494 views
in Technique[技术] by (71.8m points)

swift - Sort filtered results in Realm by matching

I have a dictionary with ~100k entries and provide a search function where the user can search for a string in english/chinese and all entries that contain this string will be displayed. An entry has the structure:

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 = ""
}

Let's say we have the following two entries:

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

and the search string is "shanghai". I filter the entries by this way:

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: ???)

Since both entries contain the search string both entries will appear, but they are not sorted by any logic yet. I would like to sort the results by the highest "coverage/matching". So first should "Shanghai" appear, then "Shanghai university", ..., and at the end entries like "Old canal between Suzhou and Shanghai". Is there any built-in realm solution?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Realm's Results have built-in methods for sorting, see Sorting in the docs.

If you want to sort based on a specific property, you can use sorted(byKeyPath:) which takes a single String representing the property name that you want to sort by:

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

Or if you want to sort based on all 3 properties that you are filtering by, you can use sorted(by:), which takes a Sequence of SortDescriptor objects, which can be created based on key paths as well:

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")])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...