简体   繁体   中英

Realm – How to query string fields that may contain leading or trailing whitespace?

How do I query for strings in my database that may contain leading or trailing whitespace without duplicating data or building a model object that can enter into an inconsistent state?

For example:

I have a model named testModel . This testModel has a property called title . I want to see if my database contains any testModel.title equal to "ABC" . But, in my database, I need to store the titles with their original, variable amount of leading/trailing whitespace, eg, " ABC " . To my knowledge, there is no way to successfully query this with Realm's current feature set, other than to store both " ABC " and "ABC" , and then query the trimmed version. In this hypothetical case, I would now have two properties, testModel.title and testModel.trimmedTitle .

I do not like this approach because I would need to update the trimmed property every time I update the non-trimmed property. Furthermore, the trimmed property should ideally be readonly , but according to the Realm documentation, readonly properties are automatically treated as ignored properties, and thus cannot be queried.

If I cannot, at the very least, make the trimmed property read-only, I'm opening the possibility for the model object to be put into an inconsistent state, even if I were to do something as ridiculous as use KVO to set the trimmed property every time an update occurs to the non-trimmed property. (I'm assuming this would at least work although I haven't yet tried it...)

Example:

testModel.title = @"ABC";
testModel.trimmedTitle = @"CDE"; // Inconsistent. Should be readonly.

I do need to preserve the original, non-trimmed string; but only in this one case do I need to work with a trimmed version of what will be in the database.

Realm does not support block based predicates, value MATCHES 'some regex' predicate strings, overridden setters and getters for non-ignored properties, and querying ignored/computed/transient properties. So, I'm at a loss as to how I should reasonably handle this.

I can't imagine this general use case is that uncommon.

Any suggestions?

Unfortunately, it does seem like Realm won't support this use-case natively. According to Realm's predicate cheat sheet (pink dots indicate queries supported by Realm), you could put together a query out of the following:

  • BEGINSWITH and ENDSWITH . The problem is that you can't tell whether the suffix/prefix are actually spaces or whether you're querying for a substring.
  • CONTAINS ; same problems as above.
  • LIKE : specify wildcards using ? and * . Unfortunately, you can't specify what characters are valid substitutes for the wildcard.

Here's a suggestion for an alternate solution: store three strings: one containing the leading whitespace, one containing the trailing whitespace, and one containing the title itself. Then have the full title as the computed property.

The full title getter will just concatenate the three strings. The setter can parse the new title value for leading and trailing whitespace and update the three underlying properties accordingly. You won't be able to query on the full title, unfortunately, but you can at least query on the whitespace-stripped title.

@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

If you need to be able to make queries on both the stripped and non-stripped forms of the title, then unfortunately I think denormalization (storing two copies of the title) will be your only option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM