2012-04-12 4 views
5


辞書の配列を小さな値の辞書で分割する良い方法を探しています。以下のように私は結果を取得したいのですがオブジェクト間の共通のキーと値のペアを使用して、より小さなキー値コード配列でNSArrayを分割します。

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

:私はこのコードを使用して管理

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

、それは動作しますが、私ここ
は、私はJSON、私はこのことから始める例です存在する場合は疑問に思っM」より正確かつ高速な何か:

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; 

} 

答えて

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]; 
} 

IDの数が多い場合は、ループの外部に可変参照を持つ述語を作成し、ループ内の各パスのID固有の述語を生成するために変数を代入するだけで、これを少し高速化することができます。

ところで、あなたの質問では、結果「フィールド」は何らかの理由でまだ配列です。私はそれが必要とは思わない。ただ一つのパスにするために更新


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

おかげでケン、私はベンチ2意志と結果を掲示し、THX – Andrea

+0

は、私は、SIM上の小さなベンチを作りました:オリジナルの方法が取りあなたが提案した0.000098 0.002735。主な相違点は、私の場合は、IDの数に等しい回数だけ循環する述語を使用して、サイクルを1回だけ繰り返すことです。 – Andrea

+0

真。私は答えを1回だけするアプローチで更新しました。 –

関連する問題