2012-04-12 33 views
5


Tôi đang cố gắng tìm một giải pháp tốt để tách một loạt từ điển trong một từ điển nhỏ hơn được khóa bằng giá trị chung giữa chúng.
Dưới đây là một ví dụ i JSON, tôi bắt đầu từ đây:Chia một NSArray trong các mảng mã hóa giá trị khóa nhỏ hơn bằng cách sử dụng cặp khóa-giá trị chung giữa các đối tượng

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

Tôi muốn để có được một kết quả như:

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

tôi quản lý bằng mã này, nó hoạt động, nhưng tôi 'm tự hỏi nếu tồn tại một cái gì đó chính xác hơn và nhanh chóng:

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; 

} 

Trả lời

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

Nếu có nhiều ID, bạn có thể tăng tốc độ này một chút bằng cách xây dựng một biến vị ngữ với tham chiếu biến ngoài vòng lặp và sau đó chỉ thay thế biến để tạo ra biến vị ngữ id cụ thể cho mỗi lần truyền qua vòng lặp .

Nhân tiện, trong câu hỏi của bạn, kết quả "trường" vẫn là một mảng vì một lý do nào đó. Tôi không nghĩ rằng nó cần phải được.


cập nhật để làm chỉ là một đường chuyền:

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

Cảm ơn Ken, tôi sẽ băng ghế dự bị hai và gửi kết quả, thx – Andrea

+0

Tôi đã thực hiện một băng ghế nhỏ trên sim: phương pháp ban đầu mất 0,000098 cái bạn đã đề xuất 0,002735. Tôi đoán rằng sự khác biệt chính là với tôi bạn chỉ cần chu kỳ một lần, bằng cách sử dụng vị ngữ bạn chu kỳ cho một số lần bằng số f các id. – Andrea

+0

Đúng. Tôi đã cập nhật câu trả lời của tôi với một cách tiếp cận mà chỉ làm cho một vượt qua. –

Các vấn đề liên quan