如何在iOS中对包含数字和名称的字符串数组进行排序

时间:2014-09-09 15:33:22

标签: ios sorting

我有一个包含字符串并希望对其进行排序的数组。 到目前为止,这么容易。

我只是使用

NSSortDescriptor *sort [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
[list sortUsingDescriptors:[NSArray arrayWithObject:sort] ];

这里的问题是,当我将它用于像“ccccc,aab,bba,123”这样的列表时 他把它分类为“123,aab,bba,ccccc”。 我想把它分类为“aab,bba,ccccc,123”

是否有iOS函数对其进行排序,数字放在列表的末尾?这些数字也是字符串。

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

将数字放在标准排序的字母之前是常规的。如果你想要数字持续,你将不得不做一些操作。

您可以使用NSPredicate来获取一个数组中的数字,然后只获取另一个数组中的数字,然后最后将它们组合起来以获得最后的数字。

// Get just the letters
NSPredicate *predLetters = [NSPredicate predicateWithFormat:@"name MATCHES %@",@"^\\p{letter}.*"];
NSArray *tempLetters = [[list copy] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
tempLetters = [tempLetters filteredArrayUsingPredicate:predLetters];

// Get just the numbers
NSPredicate *predNumbers = [NSPredicate predicateWithFormat:@"NOT (name MATCHES %@)",@"^\\p{letter}.*"];
NSArray *tempNumbers = [[list copy] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
tempNumbers = [tempNumbers filteredArrayUsingPredicate:predNumbers];

// Combine arrays
NSMutableArray *tempCombined = [[NSMutableArray alloc] initWithArray:tempLetters];
[tempCombined addObjectsFromArray:tempNumbers];

// Rename to 'list'
list = [tempCombined copy];

澄清:此代码仅基于name的第一个字符。我从你的问题中假设你没有任何names同时包含字母和数字。如果你这样做,那么过滤器就会脱离第一个字符,name中的其余字符将按照标准惯例进行排序。您可能必须设置一个递归函数或其他东西来处理对包含字母和数字的name进行排序,如果您希望始终首先处理字母,即使它们是字符串中的第5个字符,例如。

编辑:感谢@Nerethar的语法修复。

答案 1 :(得分:1)

现在按照我想要的方式工作,只需稍微修改一下GeneralMike的代码,就可以归功于他。 我发布了工作代码,并在此处解释了这些更改。

NSSortDescriptor *sort [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];

// Get just the letters
NSPredicate *predLetters = [NSPredicate predicateWithFormat:@"name MATCHES %@",@"^\\p{letter}.*"];
NSArray *tempLetters = [[list copy] sortedArrayUsingDescriptors:@[sort]];
tempLetters = [tempLetters filteredArrayUsingPredicate:predLetters];

// Get just the numbers
NSPredicate *predNumbers = [NSPredicate predicateWithFormat:@"NOT (name MATCHES %@)",@"^\\p{letter}.*"];
NSArray *tempNumbers = [[list copy] sortedArrayUsingDescriptors:@[sort]];
tempNumbers = [tempNumbers filteredArrayUsingPredicate:predNumbers];

// Combine arrays
NSMutableArray *tempCombined = [[NSMutableArray alloc] initWithArray:tempLetters];
[tempCombined addObjectsFromArray:tempNumbers];

// Rename to 'list'
list = [tempCombined copy];

显然你不能使用<和>比较我发现的字符串。但要检查它是否以字母开头,这个正则表达式正常。有关更多信息,请查看: How can i filter NSMutableArray by firstName with non-alphabetical characters

其他更改只是语法原因,但正如GeneralMike先前所说,他没有时间进行实际检查。

filteredArrayWithPredicate需要被filterArrayUsingPredicate

sortedArrayUsingDescriptors: sort 需要sortArrayUsingDescriptors: @ [sort] 否则你会收到施法警告。

主持人是否可以像编辑工作代码一样善良,加上对他的帖子的解释,以便他可以获得答案和赞成票的功劳?

谢谢

答案 2 :(得分:0)

使用自定义比较器:

sortedArray = [list sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    id aValue = [a valueForKey:@"name"];
    id bValue = [b valueForKey:@"name"];
    //check if both aValue and bValue are numbers or if both aValue and bValue are both strings
    //if so, then use normal sort order
    //else, if aValue is a string, and bValue is a number, then return NSOrderedAscending
    //else (aValue is a number, and bValue is a string), return NSOrderedDescending
}];