2015-11-05 1 views
0

J'ai une collection de balises rapportant leurs distances et je travaille dans un projet avec une architecture établie que je ne peux pas changer, sinon je pourrais avoir l'option pour différentes approches.NSSortDescriptor tri sur les propriétés qui pourraient être nul

Il existe un tableau existant d'objets balises qui indiquent leurs distances moyennes. Le code existant trie le tableau de balises sur leur distance moyenne, stocké dans une propriété appelée _averageDistance. Tout fonctionne bien jusqu'à ce qu'une balise hors ligne signale un _averageDistance indiquant qu'elle n'est pas disponible.

Le currentcode est la suivante:

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; 
} 

est-il un moyen de contrôler la façon dont les valeurs sont nulles traitées lors du tri NSArray? Merci!

Répondre

2

Vous pouvez utiliser une méthode de tri différent pour forcer les balises non disponibles à la fin:

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

Cela rend toute balise dont averageDistance est nil comparer plus grande que toute autre balise, ce qui est le contraire de ce qui se passe actuellement. Les balises indisponibles se retrouveront (dans l'ordre arbitraire entre elles) au-delà de toute autre balise dans le tableau trié.

Ou vous pouvez filtrer le tableau avant le tri:

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

Cela se traduira par allAvailableBeacons ne contenant que des balises dont averageDistance n'est pas nil. Vous triez ensuite ce tableau au lieu de l'original.

0

Je voudrais écrire une coutume NSSortDescriptor pour gérer les valeurs nulles comme bon vous semble:

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];} 
               }];