规范化或规范化Core Data的字符串? [英] Normalize or Canonicalize string for Core Data?

查看:144
本文介绍了规范化或规范化Core Data的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看过一些关于核心数据的WWDC视频,我计划维护一个规范化的文本属性。假设我有以下数据:

  originalString normalizedString(+小写?)
Ønskeronsker
onsker onsker
Onsker onsker

当我查询模型时,它由'normalizedString',以便它忽略大小写和Ø(或其他字符)。我也想要能够运行一个查询,如开头为'o',并返回上面的3个字。



我试图避免做某事例如:

  [NSPredicate predicateWithFormat:@(originalString like [cd]%@)... 

用于查询模型。
我也试图使用'originalString'来排序。



我尝试了两种不同的方法,但没有成功,我的标准化字符串仍然保存as the originalString(I override the setter in a category I created):


  1. 调用decomposedStringWithCanonicalMapping:

      // ... 
    [normalizedString decomposedStringWithCanonicalMapping];
    // ...


  2. 后续此示例

      // ... 
    CFStringNormalize((CFMutableStringRef)normalizedString,kCFStringNormalizationFormD);
    CFStringFold((CFMutableStringRef)normalizedString,kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive,NULL);


有关如何完成目标的任何建议?



编辑:
这是我重写的setter,我知道它被调用:

   - (void)setNormalizedName:(NSString *)newNormalizedName 
{
NSMutableString * normalizedString;
if(![self.lastName length] == 0){
normalizedString = [NSMutableString stringWithString:self.lastName];
} else {
normalizedString = [NSMutableString stringWithString:self.firstName];
}

// CFStringNormalize((CFMutableStringRef)normalizedString,kCFStringNormalizationFormD);
// CFStringFold((CFMutableStringRef)normalizedString,kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive,NULL);
[normalizedString decomposedStringWithCanonicalMapping];

[self willChangeValueForKey:@normalizedName];
[self setPrimitiveValue:normalizedString forKey:@normalizedName];
[self didChangeValueForKey:@normalizedName];
}


解决方案

主要属性(例如 firstName lastName ),而不是derived属性的setter。 / p>

另请注意, decomposedStringWithCanonicalMapping 会返回一个新字符串,所以不会
修改接收者。



代码大致看起来像这样(不是编译器检查):

   - (void)setFirstName:(NSString *)firstName 
{
[self willChangeValueForKey:@firstName];
[self setPrimitiveValue:firstName forKey:@firstName];
[self didChangeValueForKey:@firstName];
[self updateNormalizedName];
}

- (void)setLastName:(NSString *)lastName
{
[self willChangeValueForKey:@lastName];
[self setPrimitiveValue:lastName forKey:@lastName];
[self didChangeValueForKey:@lastName];
[self updateNormalizedName];
}

- (void)updateNormalizedName
{
NSString * normalizedString;
if([self.lastName length]> 0){
normalizedString = [self.lastName decomposedStringWithCanonicalMapping];
} else {
normalizedString = [self.firstName decomposedStringWithCanonicalMapping];
}
self.normalizedString = normalizedString;
}


I've watched some of the WWDC videos on Core Data and I'm planning on maintaining a canonicalized text property. Let's say I have the following data:

originalString              normalizedString (+lowercase?)
Ønsker                      onsker
onsker                      onsker
Onsker                      onsker

When I query my model, I want to sort it by 'normalizedString' so that it ignores the case and the Ø (or other characters). I also want to be able to run a query like "starts with 'o'" and have it return the 3 words above.

I was trying to avoid to do something like:

[NSPredicate predicateWithFormat:@"(originalString like[cd] %@)"...

for querying the model. I was also trying to use the 'originalString' for my sorting.

I've tried two different approaches with no success, my normalized string is still saved as the originalString (I override the setter in a category I created):

  1. Calling decomposedStringWithCanonicalMapping:

    // ...
    [normalizedString decomposedStringWithCanonicalMapping];
    // ...
    

  2. Followed this example:

    // ...
    CFStringNormalize((CFMutableStringRef)normalizedString, kCFStringNormalizationFormD);
    CFStringFold((CFMutableStringRef)normalizedString, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive, NULL);
    

Any ideas on how I can accomplish my goal?

Edit: Here's my overridden setter, which I know it gets called:

- (void) setNormalizedName:(NSString *)newNormalizedName
{
    NSMutableString *normalizedString;
    if (![self.lastName length] == 0) {
        normalizedString = [NSMutableString stringWithString:self.lastName];
    } else {
        normalizedString = [NSMutableString stringWithString:self.firstName];
    }

//    CFStringNormalize((CFMutableStringRef)normalizedString, kCFStringNormalizationFormD);
//    CFStringFold((CFMutableStringRef)normalizedString, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive, NULL);
    [normalizedString decomposedStringWithCanonicalMapping];

    [self willChangeValueForKey:@"normalizedName"];
    [self setPrimitiveValue:normalizedString forKey:@"normalizedName"];
    [self didChangeValueForKey:@"normalizedName"];
}

解决方案

You should override the setters for the "primary" properties (e.g. firstName, lastName), and not the setter for the "derived" property.

Also note that decomposedStringWithCanonicalMapping returns a new string, it does not modify the receiver.

The code could roughly look like this (not compiler checked):

- (void) setFirstName:(NSString *)firstName
{
    [self willChangeValueForKey:@"firstName"];
    [self setPrimitiveValue:firstName forKey:@"firstName"];
    [self didChangeValueForKey:@"firstName"];
    [self updateNormalizedName];
}

- (void) setLastName:(NSString *)lastName
{
    [self willChangeValueForKey:@"lastName"];
    [self setPrimitiveValue:lastName forKey:@"lastName"];
    [self didChangeValueForKey:@"lastName"];
    [self updateNormalizedName];
}

- (void) updateNormalizedName
{
    NSString *normalizedString;
    if ([self.lastName length] > 0) {
        normalizedString = [self.lastName decomposedStringWithCanonicalMapping];
    } else {
        normalizedString = [self.firstName decomposedStringWithCanonicalMapping];
    }
    self.normalizedString = normalizedString;
}

这篇关于规范化或规范化Core Data的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆