Ordenar diferentes entidades en un NSMutableArray por fecha
Frecuentes
Visto 89 equipos
0
I am pushing 3 different entities in a NSMutableArray
, and need to compare them on the date.
But the 3 different entities have different names for the date.
I use the 3 entities: Birthday, Events, OtherEvents with the date properties: birthday, day, date.
Does anyone has any idea how to sort it like this. It has about 40 properties in it so its not a single comparison.
Gracias por adelantado
2 Respuestas
2
Prueba esto:
[eventsArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDate *date1 = nil;
NSDate *date2 = nil;
if ([obj1 isKindOfClass:[Birthday class]]) {
date1 = [obj1 birthday];
} else if ([obj1 isKindOfClass:[Events class]) {
date1 = [obj1 day];
} else if ([obj1 isKindOfClass:[OtherEvents class]) {
date1 = [obj1 date];
}
if ([obj2 isKindOfClass:[Birthday class]]) {
date2 = [obj2 birthday];
} else if ([obj2 isKindOfClass:[Events class]) {
date2 = [obj2 day];
} else if ([obj isKindOfClass:[OtherEvents class]) {
date2 = [obj2 date];
}
return [date1 compare:date2];
}];
contestado el 28 de mayo de 14 a las 14:05
Oke good one, but this is only from two objects.. How do i do this with 40? do i have to compare the first two with eachother and the third with the last two and so on...? - David Raijmakers
Todo NSMutableArray
's sortUsing
methods work over every object in the array. - Austin
Okay thanks i will try it soon and then i will accept yours. Thanks already for the effort - David Raijmakers
1
You can maintain a dictionary mapping the class to the right property.
For sorting access it with Key Value Coding.
NSDictionary *dateMapper = @{NSStringFromClass([Birthday class]): @"birthday",
NSStringFromClass([Event class]): @"day",
NSStringFromClass([OtherEvents class]): @"date"};
[eventsArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDate *date1 = [obj1 valueForKey: dateMapper[NSStringFromClass([obj1 class])]];
NSDate *date2 = [obj2 valueForKey: dateMapper[NSStringFromClass([obj2 class])]];
return [date1 compare:date2];
}];
I wrote a complete command line Código de muestra.
These are the model classes I use:
@interface Birthday : NSObject
@property (nonatomic, strong) NSDate *birthday;
@property (nonatomic, copy) NSString *name;
-(id)initWithName:(NSString *) name birthdayDate:(NSDate *) date;
@end
@implementation Birthday
-(id)initWithName:(NSString *) name birthdayDate:(NSDate *) date
{
if(self = [super init]){
_birthday = date;
_name = name;
};
return self;
}
-(NSString *)description
{
return [NSString stringWithFormat:@"Birthday:\t %@: %@", _birthday, _name];
}
@end
@interface Event : NSObject
@property (nonatomic, strong) NSDate *day;
@property (nonatomic, copy) NSString *title;
-(id)initWithTitle:(NSString *) title date:(NSDate *) date;
@end
@implementation Event
-(id)initWithTitle:(NSString *) title date:(NSDate *) date;
{
if(self = [super init]){
_day = date;
_title = title;
};
return self;
}
-(NSString *)description
{
return [NSString stringWithFormat:@"Event:\t\t %@: %@", _day, _title];
}
@end
@interface OtherEvent : NSObject
@property (nonatomic, strong) NSDate *date;
@property (nonatomic, copy) NSString *title;
-(id)initWithTitle:(NSString *) title date:(NSDate *) date;
@end
@implementation OtherEvent
-(id)initWithTitle:(NSString *) title date:(NSDate *) date;
{
if(self = [super init]){
_date = date;
_title = title;
};
return self;
}
-(NSString *)description
{
return [NSString stringWithFormat:@"OtherEvent: %@: %@", _date, _title];
}
@end
This code fills the array. Note that I use a rather unknown c syntax called statement expression to create the dates. I prefer them in such sample code to structure it, but you don't need to use it:
NSMutableArray *array = [@[] mutableCopy];
[array addObject:[[Birthday alloc] initWithName:@"Bibo"
birthdayDate:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.year = 1969;
comps.month = 7;
comps.day = 15;
[[NSCalendar currentCalendar] dateFromComponents:comps];
})
]];
[array addObject:[[Birthday alloc] initWithName:@"Jimi Hendrix"
birthdayDate:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.year = 1942;
comps.month = 11;
comps.day = 27;
[[NSCalendar currentCalendar] dateFromComponents:comps];
})
]];
[array addObject:[[Event alloc] initWithTitle:@"Vacation end"
date:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.year = 2014;
comps.month = 6;
comps.day = 21;
[[NSCalendar currentCalendar] dateFromComponents:comps];
})
]];
[array addObject:[[Birthday alloc] initWithName:@"Samson"
birthdayDate:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.year = 1977;
comps.month = 9;
comps.day = 3;
[[NSCalendar currentCalendar] dateFromComponents:comps];
})
]];
[array addObject:[[Event alloc] initWithTitle:@"Vacation begin"
date:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.year = 2014;
comps.month = 6;
comps.day = 1;
[[NSCalendar currentCalendar] dateFromComponents:comps];
})
]];
[array addObject:[[OtherEvent alloc] initWithTitle:@"Woodstock Music and Art Festival"
date:(
{
NSDateComponents *comps = [[NSDateComponents alloc] init];
comps.year = 1969;
comps.month = 15;
comps.day = 8;
[[NSCalendar currentCalendar] dateFromComponents:comps];
})
]];
Now I do the sorting
NSDictionary *dateMapper = @{NSStringFromClass([Birthday class]): @"birthday",
NSStringFromClass([Event class]): @"day",
NSStringFromClass([OtherEvent class]): @"date"};
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDate *date1 = [obj1 valueForKey: dateMapper[NSStringFromClass([obj1 class])]];
NSDate *date2 = [obj2 valueForKey: dateMapper[NSStringFromClass([obj2 class])]];
return [date1 compare:date2];
}];
for (id obj in array) {
NSLog(@"%@", obj);
}
Esto resulta en:
Birthday: 1942-11-26 23:00:00 +0000: Jimi Hendrix
Birthday: 1969-07-14 23:00:00 +0000: Bibo
OtherEvent: 1970-03-07 23:00:00 +0000: Woodstock Music and Art Festival
Birthday: 1977-09-02 23:00:00 +0000: Samson
Event: 2014-05-31 22:00:00 +0000: Vacation begin
Event: 2014-06-20 22:00:00 +0000: Vacation end
contestado el 28 de mayo de 14 a las 19:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas ios sorting nsmutablearray block nssortdescriptor or haz tu propia pregunta.
Create a category on each class that unifies the 3 different dates under the
sortDate
¿propiedad? - David RönnqvistAnother very similar solution is to define a
SortableByDate
protocol that defines asortDate
property. Then have the different classes implement that protocol. - David RönnqvistEither unify the name of the date object, make a secondary object that is a copy or reference of the first, or setup a three case sort with
[object isKindOfClass:]
checks on every object. - Putz1103How would you sort it then Putz 1103? how can i sort an array if an object is kind of class ... you need to sort the whole array right? - David Raijmakers
I think @DavidRönnqvist has the best ideas (a little better than the posted answers). One more: just implement a comparator on each object (polymorphism, in OO 101). If date order is the dominant sort in most cases, the comparator could even be named -- and thus override -- compare:. - danh