我在SO上遇到了很多问题(比如this one),但我仍然需要一些帮助。
我需要我的sqlite选择按斯洛文尼亚字母排序(字母č在c之后,字母š在s之后,字母ž在z之后)。
以下是我使用的代码:
static int sqlite3SloCollate(void * foo, int ll, const void *l, int rl,
const void *r){
NSString *left = [NSString stringWithCharacters:l length:ll];
NSString *right = [NSString stringWithCharacters:r length:rl];
//THIS IS WHERE I DON'T KNOW HOW TO COMPARE CHARACTERS
NSComparisonResult rs = [left compare:right options:NSForcedOrderingSearch];
return rs;
}
sqlite3_create_collation(database, "SLOCOLLATE", SQLITE_UTF8, NULL, &sqlite3SloCollate);
querySQL = [NSString stringWithFormat: @"SELECT s.id FROM lyrics l INNER JOIN song s ON (l.idSong=s.id) WHERE content LIKE '%%%@%%' GROUP BY s.id ORDER BY s.title COLLATE SLOCOLLATE;",searchString];
我应该使用哪种NSOrdering类型?或者我必须编写自己的比较功能(你能举个例子)吗?
答案 0 :(得分:1)
我认为这个功能可以帮到你:
- (NSComparisonResult)compare:(NSString *)aString options:(NSStringCompareOptions)mask range:(NSRange)range locale:(id)locale
(来自Apple documentation)。
您可以使用以下方式创建区域设置:
- (id)initWithLocaleIdentifier:(NSString *)string
(来自Apple NSLocale Class Documentation)。
这段代码可以解决问题:
NSRange range = NSMakeRange(0, [left length]);
id locale = [[NSLocale alloc] initWithLocaleIdentifier:@"sl_SI"];
NSComparisonResult rs = [left compare:right options:NSForcedOrderingSearch range:range locale:locale];
我希望这会有所帮助。
答案 1 :(得分:1)
@DCMaxxx的答案大部分都是。加上您需要使用stringWithUTF8String
的评论。但还有一些问题。
1)stringWithUTF8String
使用以null结尾的c字符串,而sqlite只提供长度且没有空终止的字符串。
2)对于要比较的字符数,我们需要采用最短的长度,而不仅仅是左边的长度。
3)当比较对比较相等时,我们需要考虑哪个字符串更长。
此处为完整代码。我使用NSMutableData对象将长度编码的字符串转换为空终止字符串。如果您倾向于使用直接C代码,它可能更快更容易。
static int sqlite3SloCollate(void * foo, int ll, const void *l, int rl,
const void *r){
NSMutableData* ld = [NSMutableData dataWithBytes:l length:ll+1];
[ld resetBytesInRange:NSMakeRange(ll, 1)];
NSString *left = [NSString stringWithUTF8String:[ld bytes]];
NSMutableData* rd = [NSMutableData dataWithBytes:r length:rl+1];
[rd resetBytesInRange:NSMakeRange(rl, 1)];
NSString *right = [NSString stringWithUTF8String:[rd bytes]];
NSRange range = NSMakeRange(0, MIN([left length],[right length]));
id locale = [[NSLocale alloc] initWithLocaleIdentifier:@"sl_SI"];
NSComparisonResult result = [left compare:right options:0 range:range locale:locale];
if (result==NSOrderedSame) {
if (ll>rl) {
result = NSOrderedDescending;
} else if (ll<rl) {
result = NSOrderedAscending;
}
}
// NSLog(@"Comparison:%@ - %@ - %li",left,right,(long)result);
return result;
}