2009-07-15 2 views
2

J'ai un magasin avec des entités qui ont des coords (x, y, z). Je veux les récupérer en utilisant un prédicat comme @ "sqrt (x x + y y + z * z) < distance".Existe-t-il un moyen d'utiliser des fonctions dans NSPredicate predicateWithFormat:

Y at-il un moyen de le faire?

J'ai essayé de le faire avec thi predicateWithFormat:

J'ai même écrit beaucoup de code qui ressemble à

NSExpression * dxExpression = [NSExpression expressionForFunction:@"from:subtract:" 
    arguments:[NSArray arrayWithObjects: 
       [NSExpression expressionForConstantValue: [NSNumber numberWithFloat:currX]], 
       [NSExpression expressionForKeyPath:@"self.xCoord"], nil] 
            ]; 
NSExpression * dxSqrExpression = [NSExpression expressionForFunction:@"multiply:by:" 
    arguments:[NSArray arrayWithObjects:dxExpression, dxExpression, nil] 
             ]; 

Mais il ne fonctionne que pour les expressions non hiérarchiques. I.e., donc dxExpression fonctionne très bien, mais quand je suis en train d'utiliser dxSqrExpression, j'obtiens l'erreur

Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: 'Unsupported function expression (-140.857 - #self.xCoord) * (-140.857 - #self.xCoord)' 

J'ai essayé sans moi, mais cela ne fonctionne pas trop.

Toute aide sera appréciée, merci.

Répondre

2

Je ne pense pas que ce que vous essayez de faire est possible, mais vous pouvez mettre en œuvre une fonction de mappage générique et Ressaisissez votre @"sqrt(x*x + y*y + z*z) < distance" prédicat en fonction renvoyant un BOOL que vous passeriez en tant que sélecteur:

@implementation NSArray(Filtering) 
- (NSArray*)arrayByMappingArrayUsingSelector:(SEL)selector, ... { 
    NSInvocation* invocation; 
    va_list arguments; 

    if (selector && [self lastObject]) { 
    va_start(arguments, selector); 
    invocation = [NSInvocation invocationUsingSelector:selector onTarget:[self lastObject] argumentList:arguments]; 
    va_end(arguments); 
    } 

    NSMutableArray *filteredArray = [NSMutableArray array]; 
    BOOL returnValue; 
    for(id object in self) { 
    [invocation invokeWithTarget:object]; 
    [invocation getReturnValue:&returnValue]; 

    if(ret) [filteredArray addObject:object]; 
    } 

    return filteredArray; 
} 
@end 
+0

Ok c'est bien vieux, mais je vais encore ajouter mon grain de sel depuis que je viens de rencontrer dans ce même problème. La solution de Nathan fonctionne mais si le magasin est grand, il peut devenir cher. Une façon d'optimiser consiste à utiliser d'abord un NSPredicate qui renvoie les résultats dans une boîte englobante au lieu de la sphère englobante que vous recherchez vraiment. Ensuite, vous pouvez utiliser la méthode de filtrage proposée par Nathan pour gagner en précision. – mprivat

-1
+0

serait préférable de créer un lien vers quelque chose, y compris un code réel exemple –

+0

Il y a un exemple là, mais il est un peu difficile de choisir: 'FONCTION (récepteur, nom_sélecteur, arguments, ...)' Ainsi, quelque chose comme; '[NSPredicate predicateWithFormat: @" FUNCTION (self, 'methodWithParameter: paramètre2:',% @,% @) ", arg1, arg2]' –

+0

Voir aussi, http://stackoverflow.com/questions/7556882/own -function-round-for-nsstring-in-nspredicate –

Questions connexes