2012-03-01 15 views
58

Tengo una matriz poblada por diccionarios, y tengo que ordenar la matriz alfabéticamente por los valores de una de las claves de los diccionarios.Ordenando NSArray de diccionarios por valor de una clave en los diccionarios

Esta es mi matriz:

tu dictus: (
    { 
    brand = Ryul; 
    productTitle = Any; 
    quantity = 1; 
    subBrand = "Ryul INJ"; 
    type = Product; 
}, 
    { 
    brand = Trol; 
    productTitle = Different; 
    quantity = 2; 
    subBrand = ""; 
    type = Brand; 
}, 
    { 
    brand = Dtor; 
    productTitle = Any; 
    quantity = 1; 
    subBrand = ""; 
    type = Product; 
}, 
    { 
    brand = Ryul; 
    productTitle = Different; 
    quantity = 2; 
    subBrand = "Ryul CHES"; 
    type = SubBrand; 
}, 
    { 
    brand = Anan; 
    productTitle = Any; 
    quantity = 1; 
    subBrand = ""; 
    type = Product; 
} 
) 

Normalmente para ordenar una matriz que va a utilizar

myArray = [uniqueProdsArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 

Pero ¿cómo ordenar el uso de la clave brand del diccionario?

Respuesta

105

creo que esto lo hará:

brandDescriptor = [[NSSortDescriptor alloc] initWithKey:@"brand" ascending:YES]; 
sortDescriptors = [NSArray arrayWithObject:brandDescriptor]; 
sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors]; 

Saqué el código de Sort Descriptor Programming Topics. Además, entra en juego el Key-Value Coding, en el que sortedArrayUsingDescriptors: enviará un valueForKey: a cada elemento en myArray, y luego usará los comparadores estándar para ordenar los valores devueltos.

+0

cómo usar esto en swift2? –

1

Basta con probar forma más fácil ...

myArray = [[NSMutableArray alloc] init]; 
NSMutableArray *tempArray = [[NSMutableArray alloc] init]; 
[tempArray removeAllObjects]; 
[tempArray addObjectsFromArray: myArray]; 

NSString *key = @"brand"; 
NSSortDescriptor *brandDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObjects:brandDescriptor,nil]; 
NSArray *sortedArray = [tempArray sortedArrayUsingDescriptors:sortDescriptors]; 
[brandDescriptor release]; 
[tempArray removeAllObjects]; 
tempArray = (NSMutableArray*)sortedArray; 
[myArray removeAllObjects]; 
[myArray addObjectsFromArray:tempArray]; 
1

se puede hacer esto.

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"d LLLL yyyy"]; 

NSComparator compareDates = ^(id string1, id string2) 
{ 
    NSDate *date1 = [formatter dateFromString:string1]; 
    NSDate *date2 = [formatter dateFromString:string2]; 

    return [date1 compare:date2]; 
}; 
NSSortDescriptor * sortDesc1 = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO comparator:compareDates]; 
[array sortUsingDescriptors:[NSArray arrayWithObjects:sortDesc1, nil]]; 
8

Conseguimos la solución mediante el método sigue

[self.jsonData sortUsingDescriptors: [NSArray arrayWithObjects: [NSSortDescriptor sortDescriptorWithKey:"fullname" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:"id" ascending:NO], nil]]; 

Donde: -

jsonData - MutableArray que mantiene el JSON de datos analizados.

fullname - los datos que queremos ordenar.

id - Datos únicos que vienen con el diccionario interno.

1
NSSortDescriptor *brandDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"Position" ascending:YES selector:@selector(localizedStandardCompare:)] autorelease]; 
     NSArray *sortDescriptors = [NSArray arrayWithObject:brandDescriptor]; 
     NSArray *sortedArray = [arrTemp sortedArrayUsingDescriptors:sortDescriptors]; 
    array_PreLagData=(NSMutableArray*)sortedArray; 

unsorted array 
Printing description of arrTemp: 
<__NSArrayM 0x10282100>(
{ 
    Milker2 = "11:03:17 AM"; 
    Position = 2; 
}, 
{ 
    Milker1 = "11:03:28 AM"; 
    Position = 25; 
}, 
{ 
    Milker3 = "11:03:18 AM"; 
    Position = 3; 
}, 
{ 
    Milker1 = "11:03:16 AM"; 
    Position = 1; 
    Strip = "11:32:32 AM"; 
}, 
{ 
    Milker1 = "11:03:21 AM"; 
    Position = 10; 
} 
) 
Sorted array 
<__NSArrayI 0x101363c0>(
{ 
    Milker1 = "11:03:16 AM"; 
    Position = 1; 
    Strip = "11:32:32 AM"; 
}, 
{ 
    Milker2 = "11:03:17 AM"; 
    Position = 2; 
}, 
{ 
    Milker3 = "11:03:18 AM"; 
    Position = 3; 
}, 
{ 
    Milker1 = "11:03:21 AM"; 
    Position = 10; 
}, 
{ 
    Milker1 = "11:03:28 AM"; 
    Position = 25; 
} 
) 

[enter link description here][1] 


    [1]: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/SortDescriptors/Articles/Creating.html#//apple_ref/doc/uid/20001845-BAJEAIEE 
3
arrSorted = [arrBrand sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
      if ([[obj1 valueForKey:@"iUserId"] integerValue] > [[obj2 valueForKey:@"iUserId"] integerValue]) { 
       return (NSComparisonResult)NSOrderedDescending; 
      } 
      if ([[obj1 valueForKey:@"iUserId"] integerValue] < [[obj2 valueForKey:@"iUserId"] integerValue]) { 
       return (NSComparisonResult)NSOrderedAscending; 
      } 
      return (NSComparisonResult)NSOrderedSame; 
     }]; 
+0

Mientras sortedArrayUsingComparator es el camino a seguir, tener hasta cuatro llamadas a "valueForKey" en lugar de dos llamadas a "objectForKey" es malo. Por cierto. Como espera diccionarios, use NSDictionary * como tipo, no como id. – gnasher729

3

Como una adición al código de QED,

NSSortDescriptor * brandDescriptor = [[NSSortDescriptor alloc] initWithKey:@"brand" ascending:YES]; 
NSArray * sortedArray = [myArray sortedArrayUsingDescriptors:@[brandDescriptor]]; 

Esto clarifica las clases de las variables y optimiza la creación de la matriz con la rápida enumeración. Gracias

6

En Switf:

var descriptor: NSSortDescriptor = NSSortDescriptor(key: "brand", ascending: true) 
var sortedResults: NSArray = results.sortedArrayUsingDescriptors([descriptor]) 
4

Uso siguiente código para ordenar el uso de la "marca" clave del diccionario ..

NSSortDescriptor * brandDescriptor = [[NSSortDescriptor alloc] initWithKey:@"brand" ascending:YES]; 
NSArray * sortDescriptors = [NSArray arrayWithObject:brandDescriptor]; 
NSArray * sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors]; 
NSLog(@"sortedArray %@",sortedArray); 

Uso siguiente código, Si a clasificar según dos teclas del diccionario; Al igual que, tecla "marca" y la clave ProductTitle del diccionario: -

NSSortDescriptor * brandDescriptor = [[NSSortDescriptor alloc] initWithKey:@"brand" ascending:YES]; 
NSSortDescriptor * productTitleDescriptor = [[NSSortDescriptor alloc] initWithKey:@"productTitle" ascending:YES]; 
NSArray * sortDescriptors = [NSArray arrayWithObjects:brandDescriptor, productTitleDescriptor, nil]; 
NSArray * sortedArray = [feedData sortedArrayUsingDescriptors:sortDescriptors]; 
NSLog(@"sortedArray %@",sortedArray); 
2

Mi código estaba fallando cuando se utiliza NSSortDescriptor así que terminamos usando un bloque que funciona muy bien en mi caso uso, cuando estoy esperando el "rango" ser un NSNumber.Si el objeto no se puede convertir a un número entero, no se ordenará, pero tampoco causará un bloqueo.

NSArray *sortedArray = [data sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
    long data1 = [[obj1 valueForKey:@"rank"] integerValue]; 
    long data2 = [[obj2 valueForKey:@"rank"] integerValue]; 
    if (data1 > data2) { 
     return (NSComparisonResult)NSOrderedDescending; 
    } 
    if (data1 < data2) { 
     return (NSComparisonResult)NSOrderedAscending; 
    } 
    return (NSComparisonResult)NSOrderedSame; 
}]; 
Cuestiones relacionadas