【问题标题】:Normalize or Canonicalize string for Core Data?为核心数据规范化或规范化字符串?
【发布时间】:2013-06-29 09:34:27
【问题描述】:

我已经观看了一些关于 Core Data 的 WWDC 视频,并且我计划维护一个规范化的文本属性。 假设我有以下数据:

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

当我查询我的模型时,我想按“normalizedString”对其进行排序,以便它忽略大小写和 Ø(或其他字符)。我还希望能够运行“以 'o' 开头”之类的查询并让它返回上面的 3 个单词。

我试图避免做类似的事情:

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

用于查询模型。 我还尝试使用“originalString”进行排序。

我尝试了两种不同的方法都没有成功,我的规范化字符串仍然保存为 originalString(我在我创建的类别中覆盖了 setter):

  1. 调用decomposedStringWithCanonicalMapping:

    // ...
    [normalizedString decomposedStringWithCanonicalMapping];
    // ...
    
  2. 已关注this example

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

关于如何实现我的目标有什么想法吗?

编辑: 这是我的重写设置器,我知道它会被调用:

- (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"];
}

【问题讨论】:

  • 请显示您的自定义setter方法的代码。我不明白为什么这不起作用。
  • @MartinR 我已经编辑了我的问题以包含我的 setter 方法。

标签: iphone ios objective-c core-data


【解决方案1】:

您应该覆盖“主要”属性的设置器(例如firstNamelastName),而不是“派生”属性的设置器。

还要注意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;
}

【讨论】:

  • 这是我试图做的,但我覆盖了 setFirstName、setLastName 和 setNormalizedName,所以我可能在那里制造了一个问题。我会用这个新方法“updateNormalizedName”再试一次。一旦我开始测试,我会将您的答案标记为正确。
  • 我尝试按照您的建议进行操作,但 decomposedStringWithCanonicalMapping 返回相同的字符串。我在上面添加了注释行,但这只会将 Ønsker 转换为 ønsker。我希望让Ønsker成为onsker。有什么想法吗?
  • @Eric:正如我现在所看到的,我的答案更侧重于“如何为标准化属性编写设置器”,但这并不能解决您的具体问题“如何将 Ø 标准化为 o” . - 后者可能是不可能的,比较stackoverflow.com/questions/16836975/ios-cfstringtransform-and 的类似问题和stackoverflow.com/questions/9376621/… 的可能解释。
猜你喜欢
  • 2010-10-10
  • 1970-01-01
  • 2013-01-18
  • 2013-02-24
  • 2013-08-21
  • 2010-12-29
  • 2018-09-29
  • 2020-02-12
  • 2012-04-25
相关资源
最近更新 更多