2012-04-12 16 views
5


मैं शब्दकोशों की एक सरणी विभाजित करने के लिए छोटे एक शब्दकोशों उन दोनों के बीच एक आम मूल्य द्वारा keyed में एक अच्छा समाधान खोजने के लिए कोशिश कर रहा हूँ के बीच एक आम कुंजी-मान पेयर का उपयोग कर छोटे कुंजी मान कोडित सरणियों में एक NSArray विभाजित करें।
यहाँ एक उदाहरण मैं JSON है, मैं इस से शुरू:वस्तुओं

{ 
    "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 
     } 
     ] 
    } 
    ] 
} 

मैं प्रबंधित इस कोड का उपयोग, यह काम करता है, लेकिन मैं 'हूँ सोच मौजूद कुछ अधिक सही और तेजी से:

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

यदि बहुत सी आईडी हैं, तो आप लूप के बाहर एक चर संदर्भ के साथ एक अनुमान बनाकर इसे थोड़ा सा गति दे सकते हैं और फिर लूप के माध्यम से प्रत्येक पास के लिए आईडी-विशिष्ट अनुमान उत्पन्न करने के लिए चर को प्रतिस्थापित कर सकते हैं ।

वैसे, आपके प्रश्न में, परिणाम "फ़ील्ड" अभी भी किसी कारण से एक सरणी है। मुझे नहीं लगता कि यह होना चाहिए।


सिर्फ एक पास बनाने के लिए अपडेट किया गया:

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

धन्यवाद केन, मैं बेंच दो और परिणाम पोस्ट, THX – Andrea

+0

मैं सिम पर एक छोटे से बेंच दिया है जाएगा: मूल विधि लेता है 0.0000 9 8 जिसे आपने 0.002735 का सुझाव दिया था। मुझे लगता है कि मुख्य अंतर यह है कि मेरे साथ आप केवल चक्र चक्र की संख्या का उपयोग करते हुए कई बार संख्याओं के बराबर चक्रों का उपयोग करते हैं। – Andrea

+0

सच है। मैंने अपना जवाब उस दृष्टिकोण के साथ अपडेट किया है जो केवल एक पास बनाता है। –

संबंधित मुद्दे