iOS 数组排序
在写 Android 数组列表排序时,想到 iOS 也有一个对应的类似排序方式,特开此篇。
Android 版参看
Android 基于 Comparator 对象列表数组排序
一、Array(数字、字符串)排序
简单点,可以使用数组的 sortedArrayUsingSelector 方法,该方法适应顺序排序;
如果要倒序,可以使用 NSSortDescriptor ,这个更强大,可以指定比较的 key;
NSMutableArray *mArrTemp = [[NSMutableArray alloc]init];
[mArrTemp addObject:@"I"];
[mArrTemp addObject:@"miss"];
[mArrTemp addObject:@"you"];
[mArrTemp addObject:@"so"];
[mArrTemp addObject:@"much"];
[mArrTemp addObject:@"tonight"];
NSLog(@"排序前 %@", mArrTemp);
NSArray *array = [mArrTemp sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"排序后 %@", array);
NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
NSArray *arrDesc = [mArrTemp sortedArrayUsingDescriptors:@[sortOrder]];
NSLog(@"倒序后 %@", arrDesc);
/*
排序前 (
I,
miss,
you,
so,
much,
tonight
)
排序后 (
I,
miss,
much,
so,
tonight,
you
)
倒序后 (
you,
tonight,
so,
much,
miss,
I
)
*/
二、Array(字典)排序
从上面倒序用的 NSSortDescriptor 可知,这个 NSSortDescriptor 可以指定比较的 key,可以用来排序字典数组。
NSMutableArray *mArrTemp = [[NSMutableArray alloc]init];
NSDictionary *dict0 = @{@"name":@"乔峰", @"atk":@1800, @"voteNum":@8989};
NSDictionary *dict1 = @{@"name":@"萧峰", @"atk":@2200, @"voteNum":@8989};
NSDictionary *dict2 = @{@"name":@"段誉", @"atk":@1800, @"voteNum":@15487};
NSDictionary *dict3 = @{@"name":@"虚竹", @"atk":@2000, @"voteNum":@5687};
NSDictionary *dict4 = @{@"name":@"木婉清", @"atk":@299, @"voteNum":@66845};
NSDictionary *dict5 = @{@"name":@"扫地僧", @"atk":@9999, @"voteNum":@1235};
[mArrTemp addObject:dict0];
[mArrTemp addObject:dict1];
[mArrTemp addObject:dict2];
[mArrTemp addObject:dict3];
[mArrTemp addObject:dict4];
[mArrTemp addObject:dict5];
for (NSDictionary *dict in mArrTemp) {
NSLog(@"排序前 %@ %@ %@", dict[@"name"], dict[@"atk"], dict[@"voteNum"]);
}
// 按投票排序,降序
NSSortDescriptor *sortAsc = [NSSortDescriptor sortDescriptorWithKey:@"voteNum" ascending:NO];
// [NSSortDescriptor sortDescriptorWithKey:@"voteNum" ascending:NO selector:@selector(compare:)];
NSArray *arrAsc = [mArrTemp sortedArrayUsingDescriptors:@[sortAsc]];
NSLog(@"=====按投票数降序=====");
for (NSDictionary *dict in arrAsc) {
NSLog(@"排序后 %@ %@ %@", dict[@"name"], dict[@"atk"], dict[@"voteNum"]);
}
// 按攻击力降序,攻击力相同按投票降序
NSArray *array = [mArrTemp sortedArrayUsingComparator:^(id obj1, id obj2){
if ([obj1 isKindOfClass:[NSDictionary class]] && [obj2 isKindOfClass:[NSDictionary class]]) {
NSInteger atk1 = [[obj1 objectForKey:@"atk"] integerValue];
NSInteger atk2 = [[obj2 objectForKey:@"atk"] integerValue];
if (atk1 > atk2) {
return NSOrderedAscending;
} else if (atk1 < atk2) {
return NSOrderedDescending;
} else {
NSInteger vote1 = [[obj1 objectForKey:@"voteNum"] integerValue];
NSInteger vote2 = [[obj2 objectForKey:@"voteNum"] integerValue];
if (vote1 > vote2) {
return NSOrderedAscending;
} else if (vote1 < vote2) {
return NSOrderedDescending;
}
}
}
return NSOrderedSame;
}];
NSLog(@"=====按攻击力降序,攻击力相同按投票降序=====");
for (NSDictionary *dict in array) {
NSLog(@"排序后 %@ %@ %@", dict[@"name"], dict[@"atk"], dict[@"voteNum"]);
}
三、Array(自定义对象)排序
同理,可以使用和上面 NSSortDescriptor 等一样的方法排序
// VoteObject.h
#import <Foundation/Foundation.h>
@interface VoteObject : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger voteNum;
@property (nonatomic, assign) NSInteger atk;
/** 初始化数据 */
- (instancetype)initWithName:(NSString *) name Atk:(NSInteger) atk VoteNum:(NSInteger) voteNum;
@end
// VoteObject.m
#import "VoteObject.h"
@implementation VoteObject
/** 初始化数据 */
- (instancetype)initWithName:(NSString *) name Atk:(NSInteger) atk VoteNum:(NSInteger) voteNum {
self = [super init];
if (self) {
_name = name;
_atk = atk;
_voteNum = voteNum;
}
return self;
}
@end
// 使用部分
...
NSMutableArray *mArrTemp = [[NSMutableArray alloc]init];
[mArrTemp addObject:[[VoteObject alloc]initWithName:@"萧峰" Atk:2200 VoteNum:8989]];
[mArrTemp addObject:[[VoteObject alloc]initWithName:@"乔峰" Atk:1800 VoteNum:8989]];
[mArrTemp addObject:[[VoteObject alloc]initWithName:@"段誉" Atk:999 VoteNum:15487]];
[mArrTemp addObject:[[VoteObject alloc]initWithName:@"虚竹" Atk:2000 VoteNum:5687]];
[mArrTemp addObject:[[VoteObject alloc]initWithName:@"木婉清" Atk:299 VoteNum:66845]];
[mArrTemp addObject:[[VoteObject alloc]initWithName:@"扫地僧" Atk:9999 VoteNum:1235]];
for (VoteObject *vote in mArrTemp) {
NSLog(@"排序前 %@ %ld %ld", vote.name, vote.atk, vote.voteNum);
}
// 按投票排序,降序
NSSortDescriptor *sortAsc = [NSSortDescriptor sortDescriptorWithKey:@"voteNum" ascending:NO];
// [NSSortDescriptor sortDescriptorWithKey:@"voteNum" ascending:NO selector:@selector(compare:)];
NSArray *arrAsc = [mArrTemp sortedArrayUsingDescriptors:@[sortAsc]];
NSLog(@"=====按投票数降序=====");
for (VoteObject *vote in arrAsc) {
NSLog(@"排序后 %@ %ld %ld", vote.name, vote.atk, vote.voteNum);
}
// 按攻击力降序,攻击力相同按投票降序
NSArray *array = [mArrTemp sortedArrayUsingComparator:^(id obj1, id obj2){
if ([obj1 isKindOfClass:[VoteObject class]] && [obj2 isKindOfClass:[VoteObject class]]) {
VoteObject *vote1 = obj1;
VoteObject *vote2 = obj2;
if (vote1.atk > vote2.atk) {
return NSOrderedAscending;
} else if (vote1.atk < vote2.atk) {
return NSOrderedDescending;
} else if (vote1.voteNum > vote2.voteNum) {
return NSOrderedAscending;
} else if (vote1.voteNum < vote2.voteNum) {
return NSOrderedDescending;
}
}
return NSOrderedSame;
}];
NSLog(@"=====按攻击力降序,攻击力相同按投票降序=====");
for (VoteObject *vote in array) {
NSLog(@"排序后 %@ %ld %ld", vote.name, vote.atk, vote.voteNum);
}
/*
=====排序前=====
乔峰 1800 8989
萧峰 2200 8989
段誉 1800 15487
虚竹 2000 5687
木婉清 299 66845
扫地僧 9999 1235
=====按投票数降序=====
木婉清 299 66845
段誉 1800 15487
乔峰 1800 8989
萧峰 2200 8989
虚竹 2000 5687
扫地僧 9999 1235
=====按攻击力降序,攻击力相同按投票降序=====
扫地僧 9999 1235
萧峰 2200 8989
虚竹 2000 5687
段誉 1800 15487
乔峰 1800 8989
木婉清 299 66845
*/
...
呃,我为什么要写多一次代码呢?!
嗯,似乎还有遗漏,待续。
END