从结果中筛选出最高数值
Filter for highest numeric value from Results
objective 是从 Realm 中获取的对象,该对象在其属性之一中包含最高的 numeric 值。该对象有一个人名(一个字符串)和一个 person_id(也是一个字符串)。
PersonClass: Object {
@objc dynamic var name = ""
@objc dynamic var person_id = ""
}
person_id可以是数字、字符串或组合。对于此过滤器,应忽略不只包含数字的所有字符串。 table 可能看起来像这样
name person_id
Henry 0000
Leroy test
Frank 3333
Steve a123
结果应该是
Henry 0000
Frank 3333 <- .last or the highest
举个简单的例子,让我们拿这个数组
let arrayOfWords = ["thing", "1", "stuff", "2"]
和一些获取字符串“1”和“2”的代码。
let swiftResults = arrayOfWords.compactMap { Int([=14=]) } //knowing that Int has limitations
swiftResults.forEach { print([=14=]) } //note we can use .last to get the last one
虽然有通过获取所有 Realm 对象然后应用 Swift 过滤器的解决方案,但问题是可能有数千人并且一旦结果对象被作为 Swift 操作枚举对象(如数组),它不仅断开了与 Realm 的连接(失去了对象的实时更新能力),而且它们不再被延迟加载,占用内存并可能使设备不堪重负。
由于领域查询不支持正则表达式,您必须检查 person_id 中是否包含任何字母并使用 @max 获取最大值。
let regexAnythingButDigits = "[^0-9]"
let maxNumericID = realm.objects(PersonClass.self).filter("person_id NOT CONTAINS[c] 'a' person_id NOT CONTAINS[c] 'b' AND ..[all letters in between]... AND person_id NOT CONTAINS[c] 'z' AND person_id.@max", regexAnythingButDigits)
根据 rs7 的回答中提供的见解,这里有一个符合问题条件的编码解决方案。
TLDR:我们构建了一个复合 AND 谓词,用于过滤 Realm 中所有没有字母字符的字符串。即获取所有不包含 'a' AND 'b' AND 'c' 等的字符串
这很重要,因为可能有数千个对象,而使用纯 Swift 进行过滤在代码方面非常简单,这样做会绕过 Realm 的延迟加载特性,整个数据集需要加载到数组中进行过滤,这可能会使设备不堪重负。
此解决方案使 Realm 对象保持惰性,从而避免了该问题。
let charStringToOmit = "abcdefghijklmnopqrstuvwxyz" //the invalid chars
let charsOmitArray = Array(charStringToOmit) //make an array of Char objects
var predicateArray = [NSPredicate]() //the array of predicates
//iterate over the array of char objects
for char in charsOmitArray {
let c = String(char) //make each char a string
let pred = NSPredicate(format: "!(person_id CONTAINS[cd] %@)", c) //craft a predicate
predicateArray.append(pred) //append the predicate to the array
}
//craft compound AND predicate
let compound = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
let realm = try! Realm()
let results = realm.objects(PersonClass.self).filter(compound).sorted(byKeyPath: "person_id")
if let lastPerson = results.last {
print(lastPerson.person_id)
}
我简化了为这个例子提供的初始数据集,并将其限制为只有 a-z 和 0-9 个字符,但可以扩展。
objective 是从 Realm 中获取的对象,该对象在其属性之一中包含最高的 numeric 值。该对象有一个人名(一个字符串)和一个 person_id(也是一个字符串)。
PersonClass: Object {
@objc dynamic var name = ""
@objc dynamic var person_id = ""
}
person_id可以是数字、字符串或组合。对于此过滤器,应忽略不只包含数字的所有字符串。 table 可能看起来像这样
name person_id
Henry 0000
Leroy test
Frank 3333
Steve a123
结果应该是
Henry 0000
Frank 3333 <- .last or the highest
举个简单的例子,让我们拿这个数组
let arrayOfWords = ["thing", "1", "stuff", "2"]
和一些获取字符串“1”和“2”的代码。
let swiftResults = arrayOfWords.compactMap { Int([=14=]) } //knowing that Int has limitations
swiftResults.forEach { print([=14=]) } //note we can use .last to get the last one
虽然有通过获取所有 Realm 对象然后应用 Swift 过滤器的解决方案,但问题是可能有数千人并且一旦结果对象被作为 Swift 操作枚举对象(如数组),它不仅断开了与 Realm 的连接(失去了对象的实时更新能力),而且它们不再被延迟加载,占用内存并可能使设备不堪重负。
由于领域查询不支持正则表达式,您必须检查 person_id 中是否包含任何字母并使用 @max 获取最大值。
let regexAnythingButDigits = "[^0-9]"
let maxNumericID = realm.objects(PersonClass.self).filter("person_id NOT CONTAINS[c] 'a' person_id NOT CONTAINS[c] 'b' AND ..[all letters in between]... AND person_id NOT CONTAINS[c] 'z' AND person_id.@max", regexAnythingButDigits)
根据 rs7 的回答中提供的见解,这里有一个符合问题条件的编码解决方案。
TLDR:我们构建了一个复合 AND 谓词,用于过滤 Realm 中所有没有字母字符的字符串。即获取所有不包含 'a' AND 'b' AND 'c' 等的字符串
这很重要,因为可能有数千个对象,而使用纯 Swift 进行过滤在代码方面非常简单,这样做会绕过 Realm 的延迟加载特性,整个数据集需要加载到数组中进行过滤,这可能会使设备不堪重负。
此解决方案使 Realm 对象保持惰性,从而避免了该问题。
let charStringToOmit = "abcdefghijklmnopqrstuvwxyz" //the invalid chars
let charsOmitArray = Array(charStringToOmit) //make an array of Char objects
var predicateArray = [NSPredicate]() //the array of predicates
//iterate over the array of char objects
for char in charsOmitArray {
let c = String(char) //make each char a string
let pred = NSPredicate(format: "!(person_id CONTAINS[cd] %@)", c) //craft a predicate
predicateArray.append(pred) //append the predicate to the array
}
//craft compound AND predicate
let compound = NSCompoundPredicate(andPredicateWithSubpredicates: predicateArray)
let realm = try! Realm()
let results = realm.objects(PersonClass.self).filter(compound).sorted(byKeyPath: "person_id")
if let lastPerson = results.last {
print(lastPerson.person_id)
}
我简化了为这个例子提供的初始数据集,并将其限制为只有 a-z 和 0-9 个字符,但可以扩展。