2013-07-19 13 views
9

Ho bisogno di visualizzare in un UITableView il contenuto di un NSDictionary restituito da un'API, rispettando l'ordine delle chiavi.NSDictionary allKeys order

sto usando:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
     NSString *key = self.data.allKeys[indexPath.section]; 
     NSArray *list = self.data[key]; 
     id data = list[indexPath.row]; 

     PSSearchCell *cell = [PSSearchCell newCellOrReuse:tableView]; 

     cell.model = data; 

     return cell; 
} 

ma come faccio self.data.allKeys, sto perdendo l'ordine delle mie chiavi. Non posso ordinarli in base al loro valore in quanto non li riguarda.

+1

Queste chiavi non sono mai state ordinate. I dizionari non hanno un ordine. –

+0

possibile duplicato di [Come posso ottenere l'ordine originale di NSDictionary/NSMutableDictionary?] (Http://stackoverflow.com/questions/3386921/how-can-i-get-original-order-of-nsdictionary-nsmutabledictionary) – Amar

risposta

1

Come tutti hanno detto, non posso ordinare le mie chiavi come appaiono nel mio ceppo NSDictionary perché un NSDictionary non è ordinato

ho chiesto alla gente dal API per restituire un array invece:

0 => name : key 1 
    value : value 1 

1 => name : key 2 
    value : value 2 

/------------------------- -------------------------------------------------- -/

Peccato che non esiste un metodo "sortedArrayUsingArray" usato così:

NSArray * arrayOne = [@"key E", @"key A", @"key C"]; 

NSArray * arrayTwo = [@"key A", @"key B", @"key C", @"key D", @"key E", @"key F"]; 

NSArray * orderedArray = [arrayOne sortedArrayUsingArray: arrayTwo]; 
+0

Non esiste un metodo simile: "sortedArrayUsingArray". Usa: http://blog.pioneeringsoftware.co.uk/2008/08/20/sorting-an-array-by-another-array/ –

23

Prova questo,

NSArray *keys = [myDictionary allKeys]; 
keys = [keys sortedArrayUsingComparator:^(id a, id b) { 
    return [a compare:b options:NSNumericSearch]; 
}]; 

NSLog(@"%@",keys); 

Ora fetch valori in base alla chiave ordinato.

EDIT

Per ordinarli in ordine alfabetico provare questo,

NSArray *keys = [myDictionary allKeys]; 
keys = [[keys mutableCopy] sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 

NSLog(@"%@",keys); 
+0

Ma Non ho cose come "Foo1", "Foo2" ... Non ho numeri nel mio nome chiave. La mia API restituisce key = "Cinema" value = elenco di cinema, key = "Theater", value = list of theatre, e ho bisogno di visualizzarli in questo ordine: prima i cinema, poi i teatri. –

+0

@NicolasRoy Si prega di controllare la risposta aggiornata. –

+0

@ βhargavḯ Non voglio ordinare questi tasti dove voglio che le chiavi vengano ricevute senza cambiare ordine. Quindi è possibile? per favore aiuto. –

0

ho scritto un metodo rapido per fare una matrice di origine (di oggetto s che sono tutti fuori ordine) e una matrice di riferimento (che ha oggetti in un ordine desiderato (e totalmente arbitrario) e restituisce una matrice in cui gli elementi dell'array sorgente sono stati riorganizzati per corrispondere all'array di riferimento.

- (NSArray *) reorderArray:(NSArray *)sourceArray toArray:(NSArray *)referenceArray 
{ 
    NSMutableArray *returnArray = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < [referenceArray count]; i++) 
    { 
     if ([sourceArray containsObject:[referenceArray objectAtIndex:i]]) 
     { 
      [returnArray addObject:[arrReference objectAtIndex:i]]; 
     } 
    } 
    return [returnArray copy]; 
} 

Si noti che questo è molto fragile. Utilizza il metodo NSArraycontainsObject:, che alla fine chiamerà NSObject's isEqual:. Fondamentalmente, dovrebbe funzionare bene per gli array di NSString s, NSNumber s, e forse NSDate s (non l'ho ancora provato), ma al di fuori di questo, YMMV. Immagino che se si provasse a passare array di UITableViewCell s o di qualche altro oggetto molto complesso, esso si spegnerebbe completamente da solo e causerebbe il crash o il ritorno della spazzatura totale. Allo stesso modo, se si dovesse fare qualcosa come passare un array di NSDate s come matrice di riferimento e un array di NSString s come matrice di origine. Inoltre, se la matrice sorgente contiene elementi non coperti nell'array di riferimento, verranno semplicemente scartati. Uno potrebbe risolvere alcuni di questi problemi aggiungendo un piccolo codice in più.

Tutto ciò detto, se si sta cercando di fare qualcosa di semplice, dovrebbe funzionare bene. Nel tuo caso, devi semplicemente inviare arrayOne dalla risposta che hai postato come matrice di origine e arrayTwo come matrice di riferimento.

0

Hai detto che stavi perdendo l'ordine delle chiavi, quindi suppongo che tu tocchi quelle chiavi da un NSArray. Destra? E in quel NSArray hai le chiavi ordinate come vuoi. E vedo anche che gli oggetti dello NSDictionary sono Arrays, giusto? Sì.Quindi nel tuo Ordered Array hai più array.

data è il nome del NSDictionary.

Quindi, tutto quello che dovete fare è portare lo NSArray (quello che avete ordinato come sempre desiderato) in questo file .m e poi usare un codice fantastico nel vostro metodo cellForRowAtIndexPath. È possibile farlo facendo quanto segue:

@interface yourViewController() 
{ 
    NSArray *yourArrayOrdered; 
} 
@end 

@implementation yourViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    yourArrayOrdered = [[NSArray alloc] initWith...:... ]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath 
{ 
    NSString *key = yourArrayOrdered[indexPath.row]; 
    NSArray *list = [self.data objectForKey:yourArrayOrdered[indexPath.row]]; 

    //your code continues here... 

    /*id data = list[indexPath.row]; //don't think you need this line 

    PSSearchCell *cell = [PSSearchCell newCellOrReuse:tableView]; 

    cell.model = data; */ 

    return cell; 
} 

E questo è tutto quello che dovete fare per mantenere l'ordine che si desidera utilizzare un NSDictionary e NSArray.

Per visualizzare meglio, nel caso in cui l'array ordinato contiene solo le stringhe sarebbe come questo:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath 
{ 
    NSString *key = yourArrayOrdered[indexPath.row]; 

    NSString *myString = [self.data objectForKey:yourArrayOrdered[indexPath.row]]; 

    cell.textLabel.text = [NSString stringWithFormat:@"THIS IS THE OBJECT %@", myString]; 

    cell.detailTextLabel.text = [NSString stringWithFormat:@"AND THIS IS THE KEY %@", key]; 

    return cell; 
} 

Speranza che aiuta.