Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 排序数组时忽略某些字符串_Iphone_Objective C_Ios4_Nsstring_Nsarray - Fatal编程技术网

Iphone 排序数组时忽略某些字符串

Iphone 排序数组时忽略某些字符串,iphone,objective-c,ios4,nsstring,nsarray,Iphone,Objective C,Ios4,Nsstring,Nsarray,我正在做一个语言应用程序,我有一个与该语言相关的词汇表(德语,以防有人感兴趣)。在我的应用程序中,我可以在按德语单词或英语单词排序tableview之间切换 当我使用以下命令时: NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type]; NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncod

我正在做一个语言应用程序,我有一个与该语言相关的词汇表(德语,以防有人感兴趣)。在我的应用程序中,我可以在按德语单词或英语单词排序tableview之间切换

当我使用以下命令时:

NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type];
NSString *string = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSArray *array = [[string componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(compare:)];
它工作得绝对完美——我的意思是,完全符合预期。然而,我想对此加以改进的是,有些词,如动词或名词,前面总是有前缀,如“to”,如“to do something”或名词前面的“the”。所以我想做的是从我的排序中排除这些,因为否则我会在数组的“t”部分下按字母顺序对所有动词进行排序,这对用户来说不是很友好

我已经查阅了有关NSString和NSArray的Apple文档,因为这就是
compare
函数的所在(除非我大错特错),我还没有找到任何对我有意义的方法。这是我第一次做这样的数据处理,所以我可能会错过一些简单的东西,所以我真的很感谢一些帮助

非常感谢


Michaeljvdw

你可能会在or上有一些运气,但我不认为这两个选项都会像你想的那样去掉冠词和介词。相反,您可能需要在
NSString
上定义一个类别,该类别提供您所寻找的特定排序样式:

 @interface NSString (MySortAdditions)
 - (NSComparisonResult)compareWithoutArticles:(NSString *)other;
 @end

 @implementation NSString (MySortAdditions)
 - (NSComparisonResult)compareWithoutArticles:(NSString *)other {
    NSMutableString *mutableSelf = [NSMutableString stringWithString:self];
    [mutableSelf
        replaceOccurrencesOfString:@"das"
        withString:@""
        options:NSCaseInsensitiveSearch
        range:NSMakeRange(0, [mutableSelf length])
    ];

    ...

    // delete articles from 'other' too

    NSCharacterSet *trimSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSString *trimmedSelf = [mutableSelf stringByTrimmingCharactersInSet:trimSet];
    NSString *trimmedOther = ...;

    return [trimmedSelf localizedCaseInsensitiveCompare:trimmedOther];
 }
 @end

然后可以使用
@选择器(compareWithoutArticles:)
作为
NSArray

的排序选择器。首先,不要使用
比较:
。改为使用本地化比较:。这一点很重要,因为
a
是作为单独的字母出现在
a
之后还是出现在
z
之后取决于语言<代码>本地化比较:负责这一点

--编辑

正如Justin所说,
localizedStandardCompare:
是要使用的选择器!我不知道那种方法。正如文档中所述,
localizedStandardCompare:
所做的不仅仅是
localizedCompare:
,尽管文档没有确切说明它的功能

--编辑结束

如果你想要更多,你需要自己去实现。为此,您可以使用类别。先申报

  @interface NSString (MichaelsSuperCompareCategory)
       -(NSComparisonResult)michaelsSuperCompare:(NSString*)string;
  @end
然后实施它

  @interface NSString (MichaelsSuperCompareCategory)
       -(NSComparisonResult)michaelsSuperCompare:(NSString*)string{
             ...
       }
  @end
通过这种方式,您可以向现有类添加方法。然后你可以用

NSArray *array = [[string componentsSeparatedByString:@"\n"] 
                                 sortedArrayUsingSelector:@selector(michaelsSuperCompare:)];
重要的是在方法名称前加上一些独特的前缀,不要意外地与Apple使用的内部方法崩溃


至于功能,据我所知,您需要自己实现。您可以使用获取当前区域设置。您可以为您知道的语言实现更好的行为,然后为未知语言默认为
localizedCompare:

你在正确的轨道上。您想要使用的方法是编写自己的方法,而不是(内置的)
compare
方法,该方法可以消除存在的“to”或“the”位,然后使用现有的
compare
方法

您的呼叫将如下所示:

NSArray *array = [[string componentsSeparatedByString:@"\n"] sortedArrayUsingSelector:@selector(myCompare:)];
使用您为
NSString
指定的自定义类别,方法如下:

// This method can be exposed in a header
- (NSComparisonResult)myCompare:(NSString*)aString
{
 NSString* selfTrimmed = [self removeArticles];
 NSString* aStringTrimmed = [s2 removeArticles];
 return [self compare:aString];
}

// This method can be kept private in the .m implementation
- (NSString*)removeArticles
{
    NSRange range = NSMakeRange(NSNotFound, 0);
    if ([self hasPrefix:@"to "])
    {
     range = [self rangeOfString:@"to "];
    }
    else if ([self hasPrefix:@"the "])
    {
     range = [self rangeOfString:@"the "];
    }

 if (range.location != NSNotFound)
 {
  return [self substringFromIndex:range.length];
 }
 else
 {
  return self;
 }
}

我会以某种方式对所有数据进行替换,例如“To”->”,然后重新加载数据。(也可以在文本编辑器中使用)


另一件需要考虑的事情是将例如“towalk”改为“walk(to)”,这可以提前完成(并且在用户按字母顺序滚动时也会减少混乱)

+1用于自定义比较。如果担心“to”或“the”可能出现在字符串开头以外的某个地方,您可以使用Shaggy的代码,但也可以验证range.location==0(或者不太优雅的子字符串WithRange是QualtoString,首先检查字符串长度,等等)。@Matthew Frederick说得好。更改为使用
hasPrefix
,这将确保
rangeOfString
只有在文章开头时才能找到它。这看起来很像我想要的,但当你说replaceCurrencesofString:@“das”with string@…时,我对代码中的位有点困惑……因为我实际上需要“das”(等)为了留在数组中,我只需要从排序中忽略它。这段代码解决了这个问题吗?谢谢你的回答,顺便说一句,我感谢你的帮助。是的,这段代码实际上做的是创建要比较的字符串的副本,然后修改这些字符串以删除任何项目和空白。也就是说,回想起来,它可能会更合理e不修改字符串,而是使用
compare:options:range:locale:
比较两个字符串的子范围,这只是出于性能原因。