2016-04-14 31 views
0

我有一個問題,從自定義對象數組創建一個NSMutableArray陣列的字典和單獨的字典(不在數組中)。自定義對象的NSMutableArray - >類似字典和NSDictionaries的NSMutableArrays的NSMutableArray

我目前有一個Person對象的NSMutableArray。我遍歷這些Person對象來創建每個對象的NSDictionaries。這些字典有三個按鍵:

NSString *firstName; 
NSString *lastName; 
Person *id; 

一些字典將有相同的姓氏和名字,但人物ID將永遠是不同的。我想將這個Person對象的NSMutableArray轉換爲NSMutableArrays和NSDictionaries的NSMutableArray - NSMutableArrays將是具有相同的firstName和lastName的NSDictionaries,而獨立的NSDictionaries將是沒有firstName和lastName的對象。原始NSMutableArray中的任何其他Person。

視覺最終的結果我渴望的是以下:

    |     |-- NSDictionary (john, smith, id) 
        |     |-- NSDictionary (john, smith, id) 
        |-- NSMutableArray |-- NSDictionary (john, smith, id) 
        |     |-- NSDictionary (john, smith, id) 
        |     |-- NSDictionary (john, smith, id) 
        | 
        |     |-- NSDictionary (bill, jones, id) 
    people  |-- NSMutableArray |-- NSDictionary (bill, jones, id) 
(NSMutableArray) |     |-- NSDictionary (bill, jones, id) 
        | 
        |-- NSDictionary (mike, smith, id) 
        | 
        |-- NSDictionary (mike, jones, id) 
        | 
        |-- NSDictionary (john, jones, id) 

我目前的執行是下面:

- (NSMutableArray*)organizeForSearchResults:(NSMutableArray*)c { 

    NSMutableArray *returnArray = [NSMutableArray alloc] init]; 

    // iterate through every person in the incoming crate 
    @autoreleasepool { 
    for (Person *person in c) { 

     // create a new person dictionary 
     NSDictionary *personDictionary = [[NSDictionary alloc] initWithObjectsAndKeys: 
             person, @"person", 
             person.firstName, @"firstName", 
             record.lastName, @"lastName", 
             nil]; 

     // if there are already objects in the top level c array 
     if (returnArray.count > 0) { 
     for (id object in returnArray) { 

      // the object in returnArray is an array of record dictionaries 
      if ([object isKindOfClass:[NSMutableArray class]]) { 

      // if the first dictionary object in the array has the same firstName 
      // and lastName, add the new person dict to the existing array of dicts 
      NSString *firstName = [(NSDictionary*)object[0] objectForKey:@"firstName"]; 
      NSString *lastName = [(NSDictionary*)object[0] objectForKey:@"lastName"]; 
      if ([firstName isEqualToString:person.firstName] && [lastName isEqualToString:person.lastName]) { 
       [object addObject:personDictionary]; 
      } 
      } 
      // if the object is a person dictionary, see if it matches the current dictionary 
      else if ([object isKindOfClass:[NSDictionary class]]) { 
      NSString *firstName = [(NSDictionary*)object objectForKey:@"firstName"]; 
      NSString *lastName = [(NSDictionary*)object objectForKey:@"lastName"]; 

      // if the current object matches the new person dict, we need to 
      // create a new array with both the existing person dict and the 
      // new person dict, add that array to returnArray, and remove the 
      // old person dict 
      if ([firstName isEqualToString:record.firstName] && [lastName isEqualToString:record.lastName]) { 
       NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:2]; 
       [newArray addObject:object]; 
       [newArray addObject:personDictionary]; 
       [returnArray addObject:newArray]; 
       [returnArray removeObject:object]; 
      } 
      // the new person dict does not match an existing array, so add it as 
      // a single item in personArray 
      else { 
       [personArray addObject:personDictionary]; 
      } 
      } 
     } 
     } 
     // there are no objects in personArray, so just add this person dict 
     else { 
     [personArray addObject:personDictionary]; 
     } 
    } 
    } 

    return personArray; 
} 

是我到目前爲止的執行在功能上是正確的,我相信,但我顯然得到了*** Collection <__NSArrayM:> was mutated while being enumerated.錯誤,因爲我正在修改它正在枚舉的NSMutableArray。我覺得我完全失去了如何正確實現這一點 - 有沒有人有如何實現這一目標的另一種策略?

回答

0

是我到目前爲止的實現功能正確的,我相信,

對不起,我想你會發現事實並非如此。但是,這是簡單的調試,我相信你會解決它。

但我顯然越來越***收集< __NSArrayM:>被枚舉時發生了變異。錯誤

觀察1:你可以把這個問題從一個突變所產生的數組你列舉 - 爲處理與for(a in b)風格的迭代。如果您使用for(a; b; c)來遍歷數組的索引,那麼您可以使用可以更改數組,您也可以使用- replaceObjectAtIndex:withObject:方法而不是addObject:/removeObject:對。

對迭代風格做出這樣的改變是不需要來解決您的問題,但這樣做可能有意義。

觀察2:您當前迭代穿過整個數組,但至多一個變化迭代的每一次執行由 - 你添加項目到一個數組,或者你用數組元素替換字典元素。一旦你做出改變,你可以終止循環 - 剩下的迭代不會做任何有用的事情。

但是,如果您使用的是for in樣式,那麼這些冗餘迭代將執行一些無用的操作 - 當您嘗試在突變數組後繼續執行迭代操作時,會出現錯誤。可以使用break語句來終止迭代。如果在進行迭代後將突變控制轉移到語句之後使用其中之一。這個聲明將適用於任何一種迭代風格。

這應該足以讓你通過這個問題,但你應該檢查你的邏輯的其餘部分 - 它可能還沒有達到你的期望。

順便說一句你可能希望改變爲用於字典構造和鍵索引的現代Objective-C語法,它會縮短你的代碼並使其更具可讀性。

HTH

相關問題