2012-04-12 6 views
5


Próbuję znaleźć dobre rozwiązanie, aby podzielić tablicę słowników w mniejszych słownikach z kluczową wartością między nimi.
Oto przykład i JSON, zacznę od tego:Dzielenie tablicy NSArray na mniejsze tablice z kodowanymi wartościami kluczowymi przy użyciu wspólnej pary klucz-wartość między obiektami

{ 
    "field": [ 
    { 
     "id": 6, 
     "name": "Andrea" 
    }, 
    { 
     "id": 67, 
     "name": "Francesco" 
    }, 
    { 
     "id": 8, 
     "name": "Maria" 
    }, 
    { 
     "id": 6, 
     "name": "Paolo" 
    }, 
    { 
     "id": 67, 
     "name": "Sara" 
    } 
    ] 
} 

Chciałbym uzyskać wynik jak:

{ 
    "field": [ 
    { 
     "6": [ 
     { 
      "name": "Andrea", 
      "id": 6 
     }, 
     { 
      "name": "Paolo", 
      "id": 6 
     } 
     ], 
     "67": [ 
     { 
      "name": "Sara", 
      "id": 67 
     }, 
     { 
      "name": "Francesco", 
      "id": 67 
     } 
     ], 
     "8": [ 
     { 
      "name": "Maria", 
      "id": 8 
     } 
     ] 
    } 
    ] 
} 

I udało się za pomocą tego kodu, to działa, ale ja „m zastanawiasz się, czy istnieje coś bardziej prawidłowy i szybki:

NSArray * array = ...; 
    NSSortDescriptor *sorter1=[[NSSortDescriptor alloc]initWithKey:@"id" ascending:YES selector:@selector(compare:)]; 
    NSSortDescriptor *sorter2=[[NSSortDescriptor alloc]initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)]; 
    NSArray *sortDescriptors=[NSArray arrayWithObjects:sorter1,sorter2,nil]; 
    array = [array sortedArrayUsingDescriptors:sortDescriptors];  
    //////////////////////////////SPLITTER 
    NSMutableArray * subcategorySplittedArray = [[NSMutableArray alloc]initWithCapacity:30]; 
    NSNumber * lastID=[[array objectAtIndex:0]objectForKey:@"id"]; 
    NSMutableArray * shopArray = [[NSMutableArray alloc]initWithCapacity:100]; 
    NSMutableDictionary * catDict = nil; 
    for (NSDictionary * dict in array) { 
     NSNumber * catID = [dict objectForKey:@"id"]; 
     if ([lastID isEqualToNumber:catID]) { 
      [shopArray addObject:dict]; 
     } 
     else { 

      catDict = [[NSMutableDictionary alloc]init ]; 
      [catDict setObject:[shopArray copy] forKey:lastID]; 
      [subcategorySplittedArray addObject:catDict]; 
      [shopArray removeAllObjects]; 
      [shopArray addObject:dict]; 
      lastID = catID; 
     } 
    } 
    catDict = [[NSMutableDictionary alloc]init ]; 
    [catDict setObject:[shopArray copy] forKey:lastID]; 
    [subcategorySplittedArray addObject:catDict]; 
    //////////////////////////////////// 
    return subcategorySplittedArray; 

} 

Odpowiedz

9
NSMutableDictionary* result = [NSMutableDictionary dictionary]; 
NSArray* ids = [array valueWithKey:@"id"]; 
NSSet* uniqueIDs = [NSSet setWithArray:ids]; 
for (NSNumber* anID in uniqueIDs) 
{ 
    NSPredicate* pred = [NSPredicate predicateWithFormat:@"id == %@", anID]; 
    NSArray* dictsForID = [array filteredArrayUsingPredicate:pred]; 
    [result setObject:dictsForID forKey:anID]; 
} 

Jeśli istnieje wiele identyfikatorów, możesz nieco przyspieszyć, budując predykat ze zmienną referencją poza pętlą, a następnie po prostu wstawiając zmienną w celu wygenerowania predykatu id dla każdego przejścia przez pętlę .

Nawiasem mówiąc, w pytaniu wynik "pole" wciąż jest tablicą z jakiegoś powodu. Nie sądzę, żeby tak było.


Updated zrobić tylko jedno hasło:

NSMutableDictionary* result = [NSMutableDictionary dictionary]; 
for (NSDictionary* dict in array) 
{ 
    NSNumber* anID = [dict objectForKey:@"id"]; 
    NSMutableArray* resultsForID = [result objectForKey:anID]; 
    if (!resultsForID) 
    { 
     resultsForID = [NSMutableArray array]; 
     [result setObject:resultsForID forKey:anID]; 
    } 

    [resultsForID addObject:dict]; 
} 
+0

Dzięki Ken, będę Ławka, thx – Andrea

+0

Zrobiłem dwa i zakładać wynik trochę ławki na karcie SIM: oryginalna metoda trwa 0.000098 ten, który zaproponowałeś 0.002735. Domyślam się, że główną różnicą jest to, że z moim, po prostu cyklujesz raz, używając predykatu, który wykonujesz cyklicznie, wielokrotnie równego liczbie identyfikatorów. – Andrea

+0

Prawda. Zaktualizowałem swoją odpowiedź, stosując podejście, które powoduje tylko jedno przejście. –

Powiązane problemy