根据值列表对 NSArray 进行排序?
Sort NSArray based on a list of values?
如何根据值列表对 NSArray 进行排序?例如:
NSArray 的一个对象有一个 属性 :
NSString* language; //- may contain value @"FR", @"NL", @"SP", @"EN", and others languages
我们如何根据值列表进行排序,例如:
NSArray* sortingByList = @[@"FR", @"NL", @"SP", @"EN"];
预期结果应如下所示:
- FR
- FR
- NL
- NL
- NL
- SP
- SP
- EN
- EN
- EN
- other languages
...
使用下面的代码对包含字符串元素的数组进行排序。
unsortedStrings 是 NSArray,其中包含未排序的字符串元素。
NSArray *sortedStrings =
[unsortedStrings sortedArrayUsingSelector:@selector(compare:)];
- (NSArray*) sortArray:(NSArray *)language withOrder:(NSArray *)sortingByList
{
return [language sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSUInteger pos1 = [sortingByList indexOfObject:obj1];
NSUInteger pos2 = [sortingByList indexOfObject:obj2];
if (pos1 < pos2)
return NSOrderedAscending;
else if (pos1 == pos2)
return NSOrderedSame;
else
return NSOrderedDescending;
}];
}
NSArray *array = @[@"FR", @"NL", @"SP",@"NL", @"EN",@"FR"];
NSArray *sortedArray = [array sortedArrayUsingSelector:
@selector(localizedCaseInsensitiveCompare:)];
NSLog(@"sortedArray is --%@",sortedArray);
输出是
SortedArray is --(
EN,
FR,
FR,
NL,
NL,
SP
)
问题 "how do I sort based on some particular interesting order" 的最佳答案总是使用其中一种获取块的方法。 使用基于 NSPredicate
的排序可以实现一些 排序,但基于块的排序更灵活,通常更容易。
这些方法采用的块将传递两个元素,并且必须 return 一个基于这两个元素的顺序的值。例如使用 NSArray
的 sortedArrayUsingComparator
:
NSArray *sorted
= [someArray
sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull x, id _Nonnull y)
{
// return NSOrderedAscending,
// NSOrderedSame or
// NSOrderedDescending based
// on the order of x and y
}
];
在您的例子中,您有一个数组 sortingByList
,它给出了所需的元素排序。大纲算法是:
- 分别从
x
和y
得到languageX
和languageY
- 获取
sortingByList
中 languageX
和 languageY
的 indexX
和 indexY
的索引(使用标准 NSArray
方法) .如果两者都没有出现在数组中,则将索引设置为比最大索引大 1。
- 比较
indexX
和 indexY
以及 return 它们的排序结果。
如果步骤 (3) 对 x
和 y
的排名相同,您可能希望根据其他 属性 对象进行二次排序。使用基于块的排序的一个好处是您可以轻松地根据任意数量的键进行排序。
如果您在实现正确排序对象的块时遇到困难,请提出一个新问题,显示您的代码,并解释您遇到困难的地方。到时候肯定会有人再帮你的。
HTH
如何根据值列表对 NSArray 进行排序?例如:
NSArray 的一个对象有一个 属性 :
NSString* language; //- may contain value @"FR", @"NL", @"SP", @"EN", and others languages
我们如何根据值列表进行排序,例如:
NSArray* sortingByList = @[@"FR", @"NL", @"SP", @"EN"];
预期结果应如下所示:
- FR - FR - NL - NL - NL - SP - SP - EN - EN - EN - other languages ...
使用下面的代码对包含字符串元素的数组进行排序。 unsortedStrings 是 NSArray,其中包含未排序的字符串元素。
NSArray *sortedStrings = [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];
- (NSArray*) sortArray:(NSArray *)language withOrder:(NSArray *)sortingByList
{
return [language sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSUInteger pos1 = [sortingByList indexOfObject:obj1];
NSUInteger pos2 = [sortingByList indexOfObject:obj2];
if (pos1 < pos2)
return NSOrderedAscending;
else if (pos1 == pos2)
return NSOrderedSame;
else
return NSOrderedDescending;
}];
}
NSArray *array = @[@"FR", @"NL", @"SP",@"NL", @"EN",@"FR"];
NSArray *sortedArray = [array sortedArrayUsingSelector:
@selector(localizedCaseInsensitiveCompare:)];
NSLog(@"sortedArray is --%@",sortedArray);
输出是
SortedArray is --(
EN,
FR,
FR,
NL,
NL,
SP
)
问题 "how do I sort based on some particular interesting order" 的最佳答案总是使用其中一种获取块的方法。 使用基于 NSPredicate
的排序可以实现一些 排序,但基于块的排序更灵活,通常更容易。
这些方法采用的块将传递两个元素,并且必须 return 一个基于这两个元素的顺序的值。例如使用 NSArray
的 sortedArrayUsingComparator
:
NSArray *sorted
= [someArray
sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull x, id _Nonnull y)
{
// return NSOrderedAscending,
// NSOrderedSame or
// NSOrderedDescending based
// on the order of x and y
}
];
在您的例子中,您有一个数组 sortingByList
,它给出了所需的元素排序。大纲算法是:
- 分别从
x
和y
得到languageX
和languageY
- 获取
sortingByList
中languageX
和languageY
的indexX
和indexY
的索引(使用标准NSArray
方法) .如果两者都没有出现在数组中,则将索引设置为比最大索引大 1。 - 比较
indexX
和indexY
以及 return 它们的排序结果。
如果步骤 (3) 对 x
和 y
的排名相同,您可能希望根据其他 属性 对象进行二次排序。使用基于块的排序的一个好处是您可以轻松地根据任意数量的键进行排序。
如果您在实现正确排序对象的块时遇到困难,请提出一个新问题,显示您的代码,并解释您遇到困难的地方。到时候肯定会有人再帮你的。
HTH