排序数组匹配字符串

时间:2014-01-03 12:45:29

标签: ios xcode sorting nsarray nssortdescriptor

我有一个字母代码的NSArray,我想排序。让我们说:@[ABC,DEF,GHI,JKL]

当用户输入搜索短语JKL时,我想以首先列出条目JKL的方式对数组进行排序。你可以说数组应该与最接近的搜索字符串匹配。

我尝试过使用NSSortDescriptor,但对此并不是很了解。这里的关键是按字母顺序排序。

这是我的代码:

NSSortDescriptor *code;
code = [[NSSortDescriptor alloc] initWithKey:@"code" ascending:YES selector:@selector(localizedStandardCompare:)];

NSArray *sortDescriptors = [NSArray arrayWithObjects:code, nil];

NSArray *sortedArray;
sortedArray = [matches sortedArrayUsingDescriptors:sortDescriptors];

NSArray *matches = [NSArray arrayWithArray: sortedArray];

任何有助于我朝着正确方向前进的帮助将不胜感激! 非常感谢。

2 个答案:

答案 0 :(得分:1)

您需要定义“对最接近的搜索字符串进行排序”的含义。如果您可以定义一个接近任意搜索字符串的算法,那么您可以实现一个搜索块/选择器,您可以使用该搜索块/选择器将数组排序为“最接近搜索字符串”顺序。

修改

您可以根据匹配字符串的字母距离对字符串进行排序。然而,这将是奇怪的,因为如果你的搜索字符串是“jjj”而你的列表是“aaa”“bbb”“iii”“jjj”“kkk”“yyy”“zzz”你的结果数组将是

“JJJ” “KKK” “III” “YYY” “BBB” “ZZZ” “AAA”

结果不会按字母顺序排列,而是根据它们与匹配字符串按字母顺序排列的顺序排列。

要做到这一点,你需要一种以数字方式表示每个字符串的方法。

脱离我的头顶,我就是这样做的:

将每个字母转换为值1-26(a = 1,z = 26)

以零值开头。

对于第一个字母,将其值添加到字符串值

对于第二个字母,添加letter_value X 26 ^ -1(字母值乘以26减去1次幂) 对于第三个字母,添加letter_value X 26 ^ -2

等等。

这会为每个数字增加越来越小的值。

现在构建一个对象数组,其中包含字符串和每个字符串与匹配字符串之间差异的绝对值

现在根据数组的“距离”值对数组进行排序。

由于此方法使用小数指数来计算值,因此排序键的速度会很慢,但它应该可以正常工作

答案 1 :(得分:-1)

我不确定你到底发生了什么,但是你说按字母顺序排序是至关重要的 - 所以这里是按字母顺序排序数组:

NSArray *codes = @[@"DEF", @"ABC", @"GHI", @"JKL"];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES];  // use ascending:NO for reverse alpha sorting
NSArray *sortedCodes = [codes sortedArrayUsingDescriptors:@[descriptor]];

如果您要查找对象的“最接近的匹配项”,您可能希望尝试使用例如NSPredicate:

NSString *searchString = @"XYZ";
NSArray *searchOptions =@[@"WXY", @"WXYZ", @"XYZ", @"XYZA", @"ZYA"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self CONTAINS[c] %@", searchString];
NSArray *containsMatches = [searchOptions filteredArrayUsingPredicate:predicate];
NSLog(@"closest search matches: %@", containsMatches);
// returns WXYZ, XYZ, XYZA

[c]表示不区分大小写。谓词中的字符串比较包括:

BEGINSWITH
  The left-hand expression begins with the right-hand expression.
CONTAINS
  The left-hand expression contains the right-hand expression.
ENDSWITH
  The left-hand expression ends with the right-hand expression.
LIKE
  The left hand expression equals the right-hand expression: ? and * are allowed as wildcard characters, where ? matches 1 character and * matches 0 or more characters.
MATCHES
  The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).

有关NSPredicates的更多信息,请参阅Apple文档:https://developer.apple.com/library/mac/documentation/cocoa/conceptual/predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-SW1

也许NSPredicate和NSSortDescriptor的组合可能会实现您的目标?