如何查询数据库中可能包含前导或尾随空格的字符串,而不重复数据或构建可能进入不一致状态的模型对象?
例如:
我有一个名为testModel
的模型。此testModel
具有名为title
的属性。我想看看我的数据库是否包含等于testModel.title
的任何"ABC"
。但是,在我的数据库中,我需要使用原始的,可变数量的前导/尾随空格来存储标题,例如" ABC "
。据我所知,除了存储" ABC "
和"ABC"
之外,没有办法使用Realm的当前功能集成功查询,然后查询修剪后的版本。在这个假设的情况下,我现在有两个属性,testModel.title
和testModel.trimmedTitle
。
我不喜欢这种方法,因为每次更新非裁剪属性时我都需要更新trimmed属性。此外,trimmed属性理想情况下应为readonly
,但根据Realm文档,readonly
属性会自动视为忽略属性,因此无法查询。
如果我不能,至少将修剪后的属性设为只读,我打开了模型对象被置于不一致状态的可能性,即使我做了像使用KVO这样荒谬的事情每次非修剪属性发生更新时设置trimmed属性。 (我假设这至少会起作用,虽然我还没有尝试过......)
示例:
testModel.title = @"ABC";
testModel.trimmedTitle = @"CDE"; // Inconsistent. Should be readonly.
我做需要保留原始的非剪裁字符串;但只有在这种情况下,我才需要使用数据库中的修剪版本。
Realm 不支持基于块的谓词,value MATCHES 'some regex'
谓词字符串,覆盖非忽略属性的setter和getter,以及查询忽略/计算/瞬态属性。所以,我不知道如何合理地处理这个问题。
我无法想象这个一般用例 不常见。
有什么建议吗?
答案 0 :(得分:0)
不幸的是,看起来Realm本身不会支持这个用例。根据Realm的predicate cheat sheet(粉红点表示Realm支持的查询),您可以将以下查询组合在一起:
BEGINSWITH
和ENDSWITH
。问题是您无法判断后缀/前缀是否实际上是空格,或者您是否查询子字符串。CONTAINS
;与上述相同的问题。LIKE
:使用?
和*
指定通配符。不幸的是,您无法指定哪些字符是通配符的有效替代。这是一个替代解决方案的建议:存储三个字符串:一个包含前导空格,一个包含尾随空格,另一个包含标题本身。然后将完整标题作为计算属性。
完整的标题getter将只连接三个字符串。 setter可以解析前导和尾随空格的新标题值,并相应地更新三个底层属性。不幸的是,你无法查询完整的标题,但你至少可以查询空格剥离的标题。
@interface MyModel : NSObject
@property NSString *title;
@property (readonly) NSString *leadingWhitespace;
@property (readonly) NSString *trailingWhitespace;
@property (readonly) NSString *normalizedTitle;
@end
@implementation MyModel
+ (NSArray *)ignoredProperties {
return @[@"title"];
}
- (void)setTitle:(NSString *)title {
// Not showing implementations
self.leadingWhitespace = [self getLeadingWhitespaceFor:title];
self.trailingWhitespace = [self getTrailingWhitespaceFor:title];
self.normalizedTitle = [title stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
}
- (NSString *)title {
return [NSString stringWithFormat:@"%@%@%@",
self.leadingWhitespace, self.normalizedTitle, self.trailingWhitespace];
}
@end
如果您需要能够对标题的剥离和非剥离形式进行查询,那么不幸的是我认为非规范化(存储标题的两个副本)将是您唯一的选择。