领域 - 如何查询可能包含前导或尾随空格的字符串字段?

时间:2017-10-10 18:02:15

标签: ios objective-c realm

如何查询数据库中可能包含前导或尾随空格的字符串,而不重复数据或构建可能进入不一致状态的模型对象?

例如:

我有一个名为testModel的模型。此testModel具有名为title的属性。我想看看我的数据库是否包含等于testModel.title的任何"ABC"。但是,在我的数据库中,我需要使用原始的,可变数量的前导/尾随空格来存储标题,例如" ABC "。据我所知,除了存储" ABC ""ABC"之外,没有办法使用Realm的当前功能集成功查询,然后查询修剪后的版本。在这个假设的情况下,我现在有两个属性,testModel.titletestModel.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,以及查询忽略/计算/瞬态属性。所以,我不知道如何合理地处理这个问题。

我无法想象这个一般用例 不常见。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

不幸的是,看起来Realm本身不会支持这个用例。根据Realm的predicate cheat sheet(粉红点表示Realm支持的查询),您可以将以下查询组合在一起:

  • BEGINSWITHENDSWITH。问题是您无法判断后缀/前缀是否实际上是空格,或者您是否查询子字符串。
  • 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

如果您需要能够对标题的剥离和非剥离形式进行查询,那么不幸的是我认为非规范化(存储标题的两个副本)将是您唯一的选择。