【问题标题】:NSSortDescriptor sorting on properties that could be nilNSSortDescriptor 对可能为 nil 的属性进行排序
【发布时间】:2015-11-05 19:27:08
【问题描述】:

我有一组信标报告它们的距离,并且我正在从事一个具有我无法更改的既定架构的项目,否则我可能会选择不同的方法。

现有的一组信标对象会报告它们的平均距离。现有代码按平均距离对信标数组进行排序,存储在名为_averageDistance 的属性中。一切正常,直到离线信标报告 nil _averageDistance 表示它不可用。

当前代码如下:

NSSortDescriptor* sortOnDistance = [NSSortDescriptor sortDescriptorWithKey:@"averageDistance" ascending:YES];
NSArray* sortDescriptors = [NSArray arrayWithObject:sortOnDistance];
NSArray* sortedBeacons = [allBeacons sortedArrayUsingDescriptors:sortDescriptors];

BOOL sameBeacon = NO;
if(![[sortedBeacons firstObject] isEqual:_closestBeacon]){
    _closestBeacon = (PTBeacon*)[sortedBeacons firstObject];
}
else {
    sameBeacon = YES;
}

在对 NSArray 进行排序时,有没有办法控制 nil 值的处理方式?谢谢!

【问题讨论】:

    标签: ios objective-c nsarray nssortdescriptor


    【解决方案1】:

    您可以使用不同的排序方法将不可用的信标强制到最后:

    [allBeacons sortedArrayUsingComparator:^(PTBeacon * firstBeacon, PTBeacon * secondBeacon){
        if( ![firstBeacon averageDistance] ){
            return (NSComparisonResult)NSOrderedAscending;
        }
        else {
            return [[firstBeacon averageDistance] compare:[secondBeacon averageDistance]];
        }
    }];
    

    这使得averageDistancenil 的任何信标比较大于任何其他信标,这与当前发生的情况相反。不可用的信标将最终(以它们之间的任意顺序)超过排序数组中的任何其他信标。

    或者你可以在排序前过滤数组:

    NSPredicate * availabilityPredicate = [NSPredicate predicateWithFormat:@"averageDistance != NIL"];
    NSArray * allAvailableBeacons = [allBeacons filteredArrayUsingPredicate:availabilityPredicate];
    

    这将导致allAvailableBeacons 仅包含averageDistance 不是nil 的信标。然后,您对该数组而不是原始数组进行排序。

    【讨论】:

      【解决方案2】:

      我会编写一个自定义的 NSSortDescriptor 来处理你认为合适的 nil 值:

      NSSortDescriptor* sortOnDistance = [NSSortDescriptor sortDescriptorWithKey:@"averageDistance"
                                                  ascending:YES
                                                 comparator:^NSComparisonResult(id obj1, id obj2)  {
                                                     if(obj1 == nil){
                                                          //customize here
                                                          return NSOrderedDescending;
                                                     }else if(obj2 == nil){
                                                          return NSOrderedAscending;
                                                     }else{  
                                                          return [obj1 compare:obj2];}
                                                     }];
      

      【讨论】:

        猜你喜欢
        • 2010-10-22
        • 2011-05-27
        • 2011-01-12
        • 1970-01-01
        • 2020-09-22
        • 2012-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多