Я хочу отсортировать список RealmSwift - PullRequest
0 голосов
/ 16 апреля 2020

Я использую RealmSwift. Данные - это отношение один-ко-многим.

У меня проблемы, потому что я не знаю, как отсортировать список в RealmSwift.

Я хочу отсортировать задачи, связанные с TaskList.

Спасибо.

class TaskList: Object, Identifiable {
    @objc dynamic var id = NSUUID().uuidString
    @objc dynamic var title = ""
    @objc dynamic var createdAt = NSDate()

    var tasks: List<Task> = List<Task>()

    override static func primaryKey() -> String? {
        return "id"
    } }

class Task: Object, Identifiable {
    @objc dynamic var id = NSUUID().uuidString
    @objc dynamic var title = ""
    @objc dynamic var createdAt = NSDate()

    private let lists = LinkingObjects(fromType: TaskList.self, property: "tasks")
    var list: TaskList { return list.first! }

    override static func primaryKey() -> String? {
        return "id"
    } }

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

Если вы хотите, чтобы ваши задачи хранились в упорядоченном виде, вам придется вручную выполнить упорядоченную вставку.

extension List {
    func insert<V: Comparable>(_ object: Element, orderedBy keyPath: KeyPath<Element, V>) {
        var index = 0
        for i in 0..<count {
            if self[i][keyPath: keyPath] >= object[keyPath: keyPath] {
                break
            }
            index = i + 1
        }
        insert(object, at: index)
    }
}

let list = TaskList()

let tasks = [
    Task(title: "J"),
    Task(title: "Z"),
    Task(title: "T"),
    Task(title: "J"),
    Task(title: "Z"),
]

tasks.forEach {
    list.tasks.insert($0, orderedBy: \.title)
}

Однако я считаю, что гораздо проще сохранять Lists несортированными и извлекать отсортированные Results всякий раз, когда мне нужно отобразить данные. Для сортировки по одному свойству просто позвоните sorted(byKeyPath:):

let sortedTasks = taskList.tasks.sorted(byKeyPath: "title")

Для сортировки по нескольким полям вызовите sorted(by:):

let sortedTasks = taskList.tasks.sorted(by: [
    SortDescriptor(keyPath: "title"),
    SortDescriptor(keyPath: "createdAt")
])

Кроме того, вы можете добавить отсортированное свойство к вашему Модель:

class TaskList: Object, Identifiable {
    @objc dynamic var id = UUID().uuidString
    @objc dynamic var title = ""
    @objc dynamic var createdAt = Date()

    var tasks = List<Task>()

    lazy var sortedTasks: Results<Task> = tasks.sorted(byKeyPath: "title")

    override class func ignoredProperties() -> [String] {
        return ["sortedTasks"]
    }

    override static func primaryKey() -> String? {
        return "id"
    }
}
0 голосов
/ 16 апреля 2020

Я думаю, что это однострочный ответ. Если вы знаете, для какого объекта TaskList вы хотите получить задачи, и хотите, чтобы они упорядочивались, скажем, по дате создания. Это сделает это

let taskResults = realm.objects(Task.self)
                       .filter("ANY lists == %@", taskList)
                       .sorted(byKeyPath: "createdAt")
0 голосов
/ 16 апреля 2020

Вы не можете получить саму LinkingObjects для сортировки, но вы можете вызвать LinkingObjects.sorted(byKeyPath:), который возвращает Results экземпляр, содержащий все элементы LinkingObjects, только что отсортированные.

class Task: Object, Identifiable {
    @objc dynamic var id = NSUUID().uuidString
    @objc dynamic var title = ""
    @objc dynamic var createdAt = NSDate()

    private let lists = LinkingObjects(fromType: TaskList.self, property: "tasks")
    lazy var sortedLists = lists.sorted(byKeyPath: "createdAt")
    var list: TaskList { return list.first! }

    override static func primaryKey() -> String? {
        return "id"
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...