订购一组对象?

Posted

技术标签:

【中文标题】订购一组对象?【英文标题】:Order an array of objects? 【发布时间】:2015-10-21 13:30:43 【问题描述】:

我在我的项目中创建了两个NSManagedObject,名为ContactGroups。这两个对象都有一个名为timeLastMessageReceived 的属性。 我有一个包含两个对象的数组。

我想按timeLastMessageReceived 的时间对该数组进行排序。

@interface Contact : NSManagedObject

...

@property (nonatomic, retain) NSDate * timeLastMessageReceived;
@property (nonatomic, retain) NSString * lastMessage;

@end



@interface Groups : NSManagedObject

@property (nonatomic, retain) NSDate * timeLastMessageReceived;
@property (nonatomic, retain) NSString * lastMessage;

@end

我正在尝试这个方法:

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSArray *newArr = [self.chatArray sortedArrayWithOptions:0 usingComparator:^NSComparisonResult(id obj1, id obj2) 
        NSDate *date1 = obj1[@"timeLastMessageReceived"];
        NSDate *date2 = obj2[@"timeLastMessageReceived"];
        return [date1 compare:date2];
    ];

但它因错误而崩溃:-[Contact objectForKeyedSubscript:]: unrecognized selector sent to instance 有任何想法吗。谢谢。

【问题讨论】:

【参考方案1】:

更新答案:

作为替代方案,您可以使用排序描述符对数组进行排序:

NSSortDescriptor *timeLastMessageReceivedDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeLastMessageReceived" ascending:YES];
NSArray *sortDescriptors = @[timeLastMessageReceivedDescriptor];
NSArray *sortedArray = [self.chatArray sortedArrayUsingDescriptors:sortDescriptors];

原答案:

我猜self.chatArray 包含Contact 类型的实例?您应该能够像这样实现比较器:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSArray *newArr = [self.chatArray sortedArrayWithOptions:0 usingComparator:^NSComparisonResult(Contact *contact1, Contact *contact2) 
    NSDate *date1 = contact1.timeLastMessageReceived;
    NSDate *date2 = contact2.timeLastMessageReceived;
    return [date1 compare:date2];
];

【讨论】:

不,包含联系人和群组类型的实例 好的,但这不是一个真正的问题,这要归功于 Objective-C 的动态运行时。由于这两种类型都实现了一个名为timeLastMessageReceived 的属性,所以一切都应该没问题。这个答案***.com/a/33260955/3617012 解释了它应该如何正确完成。 我已经用另一种方法对数组进行排序更新了我的答案(无需像添加协议那样重写其余代码)。【参考方案2】:

您可以在NSDictionary 的实例上使用[] 运算符(即-objectForKeyedSubscript:)。正如错误消息所述,您正在处理Contact 的实例,因此它不支持下标运算符。

您展示了timeLastMessageReceived 只是Contact 上的一个属性,因此您应该能够使用默认的属性访问语法:

    NSDate *date1 = obj1.timeLastMessageReceived;
    NSDate *date2 = obj2.timeLastMessageReceived;

【讨论】:

我在尝试此操作时遇到错误:在“__strong id”类型的对象上找不到属性“timeLastMessgaeReceived” 是的,这是意料之中的。请参阅@Marcos Crispino 的答案以了解如何解决。【参考方案3】:

我将创建一个由联系人和组实现的协议,它定义了timeLastMessageReceived 属性。

@protocol ContactOrGroupProtocol
@property (nonatomic, retain) NSDate * timeLastMessageReceived;
@end

那么,比较器块将是:

^NSComparisonResult(id<ContactOrGroupProtocol> obj1, id<ContactOrGroupProtocol> obj2) 
    NSDate *date1 = obj1.timeLastMessageReceived;
    NSDate *date2 = obj2.timeLastMessageReceived;
    return [date1 compare:date2];
];

【讨论】:

我需要在哪里创建这个协议?【参考方案4】:

另一种方法是在GroupsContact类中实现比较方法

- (NSComparisonResult)compareLastMessageReceived:(Groups *)group 
  return [self.timeLastMessageReceived compare:group.timeLastMessageReceived];


- (NSComparisonResult)compareLastMessageReceived:(Contact *)contact 
  return [self.timeLastMessageReceived compare:contact.timeLastMessageReceived];

并致电sortedArrayUsingSelector:

NSArray *newArr = [self.chatArray sortedArrayUsingSelector:@selector(compareLastMessageReceived:)];

【讨论】:

以上是关于订购一组对象?的主要内容,如果未能解决你的问题,请参考以下文章

通过特定的 ManyToMany 对象订购 Django QuerySet

python 统一可清洗对象列表的最快方法(已订购)

csharp 创建按价格订购的3种产品的匿名对象

通过Java中的键编号订购地图对象

Core Data 使用多个上下文中的新对象从后台线程订购一对多关系保存

订购一组正则表达式模式或获取最大的正则表达式匹配