我使用Core Data
从NSFetchRequest
存储中提取数据并将数据存储在array
中 - 一切正常。下一步,我想使用array
对NSSortDescriptors
进行排序,如下所示:
array = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO],
[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO comparator:^NSComparisonResult(id obj1, id obj2) {
if ([[[array objectAtIndex:[obj2 integerValue]] valueForKey:@"lessImportantItems"] containsObject:[array objectAtIndex:[obj1 integerValue]]]) {
return (NSComparisonResult)NSOrderedAscending;
} else {
return (NSComparisonResult)NSOrderedDescending;
}
}],
[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:NO], nil]];
我遇到的问题是第二个NSComparator
中的NSSortDescriptor
块未被调用(我尝试NSLog
)。为了给我的数据结构提供一些背景知识,这里是相关的Core Data
对象图部分:
应用程序的作用是将项目相互比较。作为第一步,配对比较中的获胜者获得score
增量。但我也标记了一个成对的优先级,即我从赢家到输家添加了一对多的lessImportantItems
关系。所以,在我的数组中,我首先尝试按score
排序,然后,当score
s相等时,我也尝试按配对优先级排序。
也许是因为我连续两次使用score
作为比较器key
?但是,另一方面,NSComparator
不允许将relationship
作为key
传递。
我似乎无法解决这个问题。有人有什么想法吗?或许我应该采取不同的方法进行排序?
答案 0 :(得分:1)
第二个排序描述符对我没有任何意义。它适用于给定的比较器
到要比较的对象的score
属性。所以在比较器里面,
obj1
,obj2
是待比较对象的得分值。
您似乎尝试使用
[array objectAtIndex:[obj1 integerValue]]
[array objectAtIndex:[obj2 integerValue]]
但这不起作用。所以第二个排序描述符应该看起来像
[NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO
comparator:^NSComparisonResult(Item *item1, Item *item2) {
// compare item1, item2 ...
}];
然后出现下一个问题:如何根据优先级比较两个对象? 您的代码主要执行以下操作:
if ([item2 valueForKey:@"lessImportantItems"] containsObject:item1]) {
return NSOrderedAscending;
} else {
return NSOrderedDescending;
}
但那不是一个合适的比较器:
NSOrderedSame
,NSOrderedDescending
订单(不是“不对称”),item1
是否仅与item2
间接相关(不是
“传递”)。但是如何对“不相关的对象”进行排序?没有独特的解决方案。如果B和C都是 如果不如A重要,那么A,B,C和A,C,B都是有效的解决方案。 比较B和C时比较器应该返回什么?
所以我认为用排序描述符无法实现 你必须选择其他一些算法,例如"Topological sorting"
答案 1 :(得分:0)
如果有人有兴趣,这就是我如何实现我追求的排序。
我只使用上面示例中的第一个NSSortDescriptor
来获取按array
排序的score
,然后我在array
上调用了另一个排序方法:< / p>
array = [array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:
[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO], nil];
array = [self applyMoreImportantPairOrdering:array];
这是方法:
+ (NSArray *)applyMoreImportantPairOrdering:(NSArray *)array {
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
[array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([[obj valueForKey:@"score"] integerValue] > 0) {
NSMutableSet *lessImportantItemsSet = [NSMutableSet setWithSet:[obj valueForKey:@"lessImportantItems"]];
for (int i = idx - 1; i >= 0; i--) {
NSManagedObject *objAbove = [array objectAtIndex:i];
if ([[obj valueForKey:@"score"] integerValue] == [[objAbove valueForKey:@"score"] integerValue]) {
if ([lessImportantItemsSet containsObject:objAbove]) {
NSUInteger idxAbove = [mutableArray indexOfObject:objAbove];
[mutableArray removeObject:obj];
[mutableArray insertObject:obj atIndex:idxAbove];
}
}
}
}
}];
return [NSArray arrayWithArray:mutableArray];
}
我需要lessImportantItemsSet
的原因是因为当我在item
中移动(删除并插入)array
时,它会失去lessImportantItems
关系。这样我就可以在完成特定item
时维护不太重要的item
列表/集。