Iphone 排序数组时忽略某些字符串
我正在做一个语言应用程序,我有一个与该语言相关的词汇表(德语,以防有人感兴趣)。在我的应用程序中,我可以在按德语单词或英语单词排序tableview之间切换 当我使用以下命令时: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
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:
比较两个字符串的子范围,这只是出于性能原因。