2011-08-29 12 views
15

Vorrei sapere come recuperare un indice di un NSArray utilizzando un NSPredicate?Come recuperare un indice di un NSArray usando un NSPredicate?

NSArray *array = [NSArray arrayWithObjects: 
        @"New-York City", 
        @"Washington DC", 
        @"Los Angeles", 
        @"Detroit", 
        nil]; 

Che tipo di metodo dovrei utilizzare al fine di ottenere l'indice di "Los Angles", dando solo un NSString
NB: @"Los An" o @"geles" dovrebbe restituire lo stesso indice ..

risposta

20

Utilizzando NSPredicate voi può ottenere array di stringhe che contengono la stringa di ricerca (sembra che ci sia alcun metodo incorporato per ottenere solo gli indici di elementi):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchString]; 
NSArray *filteredArray = [array filteredArrayUsingPredicate: predicate]; 

si può ottenere solo con gli indici indexesOfObjectsPassingTest: metho D:

NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ 
    NSString *s = (NSString*)obj; 
    NSRange range = [s rangeOfString: searchString]; 
    return range.location != NSNotFound; 
}]; 

Se si desidera ottenere un solo elemento che contiene la stringa è possibile utilizzare simili indexOfObjectPassingTest: metodo per questo.

+0

si dice range.origin non esiste ... – wagashi

+0

@wagashi, uh grazie, nome della proprietà sbagliato. Divertente sei il primo ad individuare un errore - dopo 7 mesi :) – Vladimir

+0

:) A proposito, dovrebbe essere "^ BOOL (id obj, NSUInteger idx, BOOL * stop)" – wagashi

21

Dovresti riuscire a farlo con i blocchi. Di seguito è riportato un frammento (non ho un compilatore a portata di mano in modo da pls si scusa per eventuali errori di battitura):

NSArray *array = [NSArray arrayWithObjects: 
       @"New-York City", 
       @"Washington DC", 
       @"Los Angeles", 
       @"Detroit", 
       nil]; 
NSString *matchCity = @"Los"; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", matchCity]; 
NSUInteger index = [self.array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { 
           return [predicate evaluateWithObject:obj]; 
        }]; 

In sostanza è possibile utilizzare l'indexOfObjectPassingTest: metodo. Questo prende un blocco (codice che segue "^") e restituisce l'indice per il primo oggetto che corrisponde al tuo predicato (o NSNotFound se non esiste alcuna corrispondenza). Il blocco scorre attraverso ogni oggetto dell'array finché non viene trovata una corrispondenza (a quel punto restituisce l'indice) o non viene trovata alcuna corrispondenza (a quel punto restituisce NSNotFound). Ecco un link per bloccare la programmazione che può aiutare a capire la logica all'interno del blocco:

https://developer.apple.com/library/ios/featuredarticles/Short_Practical_Guide_Blocks/

+0

Ottima risposta grazie –

1

farei questo ..

NSString * stringToCompare = @"geles"; 
int foundInIndex; 

for (int i=0; i<[array count]; i++){ 

    NSString * tryString = [[array objectAtIndex:i] description]; 

    if ([tryString rangeOfString:stringToCompare].location == NSNotFound) { 
     // no match 
    } else { 
     //match found 
     foundInIndex = i; 
    } 



}// end for loop 
+0

fammi fare alcuni commenti: 1) se non ci sono elementi corrispondenti alla stringa, il tuo foundInIndex rimarrà non inizializzato e non potrai usarlo. 2) puoi ottenere prestazioni migliori usando l'enumerazione veloce o l'enumerazione basata su blocchi 3) non ha senso usare il metodo -description qui 4) essere consapevoli che il tuo codice troverà l'ultimo elemento dell'array che contiene la stringa di ricerca – Vladimir

3

Trovato un approccio alternativo utile in cui la ricerca è più complessa in quanto consente predicato da utilizzare per trovare l'oggetto poi opporsi per trovare index:

-(NSIndexPath*) indexPathForSelectedCountry{ 
    NSUInteger indexToCountry = 0; 
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isoCode = %@",self.selectedCountry.isoCode]; 
    NSArray * selectedObject = [self.countryList filteredArrayUsingPredicate:predicate]; 
    if (selectedObject){ 
     if (self.searchDisplayController.isActive){ 
      indexToCountry = [self.searchResults indexOfObject:selectedObject[0]]; 
     }else{ 
      indexToCountry = [self.countryList indexOfObject:selectedObject[0]]; 
     } 
    } 
    return [NSIndexPath indexPathForRow:indexToCountry inSection:0]; 
} 
0

sulla base di @Louie risposta, invece di utilizzare per loop avevo usato un blocco di enumerazione che funzionava per me.

ho fatto questo: -

NSString *stringToCompare = @"xyz"; 

[myArray enumerateObjectsUsingBlock:^(id *Obj, NSUInteger idx, BOOL * _Nonnull stop) { 
NSString * tryString = [[myArray objectAtIndex:idx] description]; 

    if ([tryString rangeOfString:stringToCompare].location == NSNotFound) { 

       // no match found 

     } else { 

       //match found and perform your operation. In my case i had removed array object at idx 

      } 
     }]; 
+0

La soluzione di Vladimir sembra più semplice per trovare indici di questo. – klefevre

Problemi correlati