gpt4 book ai didi

ios - 在 Realm 中组合查询?

转载 作者:行者123 更新时间:2023-11-29 01:54:30 26 4
gpt4 key购买 nike

我的模型中有这两个对象:

留言:

class Message: Object {
//Precise UNIX time the message was sent
dynamic var sentTime: NSTimeInterval = NSDate().timeIntervalSince1970
let images = List<Image>()
}

图片:

class Image: Object {
dynamic var mediaURL: String = ""
var messageContainingImage: Message {
return linkingObjects(Message.self, forProperty: "images")[0]
}
}

我想形成一个返回消息和图像的查询,消息按 sentTime 排序和按其 messageContainingImage 排序的图像的发送时间。它们会被分类在一起。

推荐的查询代码是这样的:

let messages = Realm().objects(Message).sorted("sentTime", ascending: true)

这将返回一个 Result<Message>目的。 Result没有办法加入另一个结果。我还有其他问题,例如,如果我可以将它们组合起来,我将如何进行排序。

其他想法:

  • 我还可以向 Image 添加一个名为 sentTime 的属性,然后一旦它们组合在一起,我就可以对它们调用该属性。
  • 我可以使它们都从具有 sentTime 的类型中继承。问题是,执行 Realm().objects(Message) 只会返回消息,而不是 Message 的子类。

我怎样才能做到这一点?

我的最终目标是在表格 View 中显示这些消息和图像结果,消息与其附加图像分开。

最佳答案

我认为,继承在这里不是正确的解决方案,这会使您的对象架构复杂化,带来更多缺点,而不是您的用例的值(value)。

让我们回到您所写的最终目标:我想您希望在一个 TableView 中将消息和图像一起显示为单独的行,其中图像遵循其消息。我的理解正确吗?

您不需要对两者进行排序,对消息进行排序并以合适的方式访问它们及其图像将确保所有内容都正确排序。主要挑战更多的是如何将这种二维数据结构作为一维序列进行枚举/随机访问。

根据您查询的数据量,您必须决定是否可以采用一种简单的方法,将它们同时保存在内存中,或者在结果之上引入一个 View 对象,该对象负责访问所有数据对象按顺序排列。

第一个解决方案可能看起来像这样:

let messages = Realm().objects(Message).sorted("sentTime", ascending: true)
array = reduce(messages, [Object]()) { (var result, message) in
result.append(message)
result += map(message.images) { $0 }
return result
}

虽然后一种解决方案更复杂,但可能看起来像这样:

// Let you iterate a list of nodes with their related objects as:
// [a<list: [a1, a2]>, b<list: [b1, b2, b3]>]
// in pre-order like:
// [a, a1, a2, b, b1, b2, b3]
// where listAccessor returns the related objects of a node, e.g.
// listAccessor(a) = [a1, a2]
//
// Usage:
// class Message: Object {
// dynamic var sentTime = NSDate()
// let images = List<Image>()
// }
//
// class Image: Object {
// …
// }
//
// FlattenedResultsView(Realm().objects(Message).sorted("sentTime"), listAccessor: { $0.images })
//
class FlattenedResultsView<T: Object, E: Object> : CollectionType {
typealias Index = Int
typealias Element = Object

let array: Results<T>
let listAccessor: (T) -> (List<E>)
var indexTransformVectors: [(Int, Int?)]
var notificationToken: NotificationToken? = nil

init(_ array: Results<T>, listAccessor: T -> List<E>) {
self.array = array
self.listAccessor = listAccessor
self.indexTransformVectors = FlattenedResultsView.computeTransformVectors(array, listAccessor)
self.notificationToken = Realm().addNotificationBlock { note, realm in
self.recomputeTransformVectors()
}
}

func recomputeTransformVectors() {
self.indexTransformVectors = FlattenedResultsView.computeTransformVectors(array, listAccessor)
}

static func computeTransformVectors(array: Results<T>, _ listAccessor: T -> List<E>) -> [(Int, Int?)] {
let initial = (endIndex: 0, array: [(Int, Int?)]())
return reduce(array, initial) { (result, element) in
var array = result.array
let list = listAccessor(element)

let vector: (Int, Int?) = (result.endIndex, nil)
array.append(vector)

for i in 0..<list.count {
let vector = (result.endIndex, Optional(i))
array.append(vector)
}

return (endIndex: result.endIndex + 1, array: array)
}.array
}

var startIndex: Index {
return indexTransformVectors.startIndex
}

var endIndex: Index {
return indexTransformVectors.endIndex
}

var count: Int {
return indexTransformVectors.count
}

subscript (position: Index) -> Object {
let vector = indexTransformVectors[position]
switch vector {
case (let i, .None):
return array[i]
case (let i, .Some(let j)):
return listAccessor(array[i])[j]
}
}

func generate() -> GeneratorOf<Object> {
var arrayGenerator = self.array.generate()
var lastObject: T? = arrayGenerator.next()
var listGenerator: GeneratorOf<E>? = nil
return GeneratorOf<Object> {
if listGenerator != nil {
let current = listGenerator!.next()
if current != nil {
return current
} else {
// Clear the listGenerator to jump back on next() to the first branch
listGenerator = nil
}
}
if let currentObject = lastObject {
// Get the list of the currentObject and advance the lastObject already, next
// time we're here the listGenerator went out of next elements and we check
// first whether there is anything on first level and start over again.
listGenerator = self.listAccessor(currentObject).generate()
lastObject = arrayGenerator.next()
return currentObject
} else {
return nil
}
}
}
}

关于ios - 在 Realm 中组合查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31034689/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com