【问题标题】:Convert filter expression to NSPredicate format将过滤器表达式转换为 NSPredicate 格式
【发布时间】:2021-02-05 20:54:49
【问题描述】:

我想使用 NSPredicate 执行此过滤方法,但在转换语法时遇到问题。

objectsCollection.filter { $0.stringIds.contains(id) }

示例类

class Object {
    let stringIds: [String]
}

let objectsCollection: [Object]
let id = "The id we want to look for"
objectsCollection.filter { $0.stringIds.contains(id) }

我对 NSPredicate 的尝试

这是我认为它会工作的方式,但似乎没有。

let filter = NSPredicate(format: "%@ IN stringIds", id)
objectsCollection.filter(filter)

错误

reason: 'Expected object of type (null) for property 'stringIds' on object of type 'Object', but received: 6011ea4dda6853a3af97376e'

【问题讨论】:

  • " 但好像没有。"会发生什么?
  • 刚刚用我收到@Alexander 的错误更新了问题
  • 在我的原始代码中,我将字符串转换为 NSPredicate(format: filterString) 我只是没有在这个问题中包含它
  • 我对领域一无所知,但 Swift 数组 filter 方法根本不需要 NSPredicate。但是,如果这是 确实 采用 NSPredicate 的其他 filter 方法,我会问,你可以在这里使用 block 谓词吗?它们更容易编写。
  • 你能举一个块谓词的例子吗?

标签: swift realm nspredicate


【解决方案1】:

有几个问题需要解决。

这个

let stringIds: [String]

不是领域对象,不会在领域中持久化。

这需要是一个 List 属性,并且列表的对象类型是另一个 Realm 对象。领域列表不支持原语(非常好)。另外,不要将您的对象命名为与另一个对象相同的名称。

class MyClass: Object {
    let myStringIdList = List<MyStringIdClass>
}

class MyStringIdClass: Object {
   @objc dynamic var myId = ""
}

然后获取列表中具有特定 stringId 的所有 MyClass 对象

let results = realm.objects(MyClass.self).filter("ANY myStringIdList.myId == %@", idToFind)

.filter 中的字符串如果需要也可以是 NSPredicate。

您也可以使用 LinkingObjects 导航回 MyClass 对象。

另一件事,当您将领域对象转换为数组时,它们会失去与领域的连接并且不再实时更新对象。

此外,Realm 对象是延迟加载的,这意味着数千个对象对内存的影响非常小。但是,将它们转换为数组会加载所有这些数据,并且可能会因大型数据集而使设备不堪重负。

【讨论】:

  • 我是否必须将字符串 id 列表放在另一个类中?
  • @MichaelJajou 看看我在MyStringIdClass 的回答 - 字符串 id 存储在 MyStringIdClass 类中,而 MyClass 有一个列表。
  • 所以没有办法只使用常规领域列表而不创建另一个对象
  • @MichaelJajou 不可能是主观的。您可以存储原语,但它们不可查询,并且这样做会丢失很多功能。最佳实践是使用一个类来存储字符串。
猜你喜欢
  • 1970-01-01
  • 2015-07-12
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
  • 1970-01-01
相关资源
最近更新 更多