简体   繁体   English

排序对象的NSArray WRT对象中包含在NSSet中的对象

[英]Sorting an NSArray of Objects WRT the objects contained in NSSet in those objects

So here is the hierarchy: 所以这是层次结构:

NSArray A contains 3 objects. NSArray A包含3个对象。 Each of those custom objects contains an NSSet of another custom objects. 每个自定义对象都包含另一个自定义对象的NSSet Each of those "another custom object"s contains a number. 每个“另一个自定义对象”都包含一个数字。

I want to sort NSArray A by that number. 我想按该数字对NSArray A进行排序。 I would not care of what object in the set was picked up. 我不在乎集合中的哪个对象被拾取。 Any object from that set would be fine. 该集合中的任何对象都可以。

Any clues on how to do it with NSSortDescriptor ? 关于如何使用NSSortDescriptor任何线索?

Key-Value coding works also with properties (or even instance variables) of custom objects, as shown in the following example. 键值编码还可以与自定义对象的属性(甚至实例变量)一起使用,如以下示例所示。 But you have to specify a collection operator that is applied to the set to choose an object for sorting, eg @max , @min or @avg . 但是您必须指定一个应用于集合的集合运算符,以选择要排序的对象,例如@max@min@avg

// The "inner object", containing a number:
@interface Custom1 : NSObject
@property (nonatomic, strong) NSNumber *number;
@end

@implementation  Custom1
@end

// The "outer object", containing a set of "inner" objects:
@interface Custom2 : NSObject
@property (nonatomic, strong) NSSet *others; // set of "Custom1 objects.
@end

@implementation  Custom2
@end

Now you can do the following: 现在,您可以执行以下操作:

Custom1 *o1 = [[Custom1 alloc] init];
o1.number = @1;
Custom1 *o2 = [[Custom1 alloc] init];
o2.number = @2;
Custom2 *p1 = [[Custom2 alloc] init];
p1.others = [NSSet setWithObjects:o1, o2, nil];

Custom1 *o3 = [[Custom1 alloc] init];
o3.number = @3;
Custom1 *o4 = [[Custom1 alloc] init];
o4.number = @4;
Custom2 *p2 = [[Custom2 alloc] init];
p2.others = [NSSet setWithObjects:o3, o4, nil];

NSArray *array = @[p1, p2];

// Sort according to maximum number in the inner object set:
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"others.@max.number" ascending:YES];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:@[sort]];

Since the data are stored in an NSArray the sort can be done using blocks, known to a sort descriptor as a comparator. 由于数据存储在NSArray ,因此可以使用块来完成排序,这对于排序描述符来说是比较器。 Note that this approach does not work with SQLite-backed Core Data fetches, which sort directly on the property value stored in the underlying data base. 请注意,这种方法不适用于SQLite支持的Core Data提取,后者直接对存储在基础数据库中的属性值进行排序。

There are several ways to go about it, this one is straight forward, bordering on the pedestrian (and I hope I got the data structure right): 有几种解决方法,这是直截了当的,与行人接壤(我希望我的数据结构正确):

NSArray *data = @[
    @{@"otherobjects":[NSSet setWithObjects: @{@"num":@2}, @{@"num":@1}, @{@"num":@4}, nil]},
    @{@"otherobjects":[NSSet setWithObjects:@{@"num":@7}, @{@"num":@9}, @{@"num":@8}, nil]}
];

NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"otherobjects" ascending:NO comparator:^NSComparisonResult(id obj1, id obj2) {

    NSNumber *n1 = [[obj1 anyObject] valueForKey:@"num"];
    NSNumber *n2 = [[obj2 anyObject] valueForKey:@"num"];
    return [n1 compare: n2];
}];

NSArray *sorted = [data sortedArrayUsingDescriptors:@[sd]];

If you want to get fancy, you can implement a method on your custom object which compares two objects, and then create a sort descriptor using that method, or you could declare a read-only property returning for instance the max or min value of the NSSet , and then simply use a normal sort descriptor on that property. 如果想花哨的话,可以在自定义对象上实现比较两个对象的方法,然后使用该方法创建排序描述符,也可以声明一个只读属性,例如返回该对象的max或min值。 NSSet ,然后仅对该属性使用普通的排序描述符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM