2015-09-19 72 views
0

我的要求是,以確定(其中觸點(一個或多個)地址簿的變化以及哪些字段(S)已經改變,因爲應用程序後打開。什麼是比較兩個NSArrays和檢測的最佳方式改變

現在我有兩個NSArrays爲arrSavedContacts(包含以前的地址簿聯繫人)和arrContacts(當前地址簿中的聯繫人),這是兩個數組看起來像

arrSavedContacts

{ 
    firstName = Gayan; 
    id = 224; 
    lastName = Udaha; 
    phones =   (
        { 
      label = Mobile; 
      value = "123456789"; 
     } 
    ); 
}, 
    { 
    firstName = Chandrananda; 
    id = 225; 
    lastName = ""; 
    phones =   (
        { 
      label = Mobile; 
      value = "234567891"; 
     } 
    ); 
}, 
    { 
    firstName = Joe; 
    id = 228; 
    lastName = B8; 
    phones =   (
        { 
      label = Mobile; 
      value = "345678912"; 
     } 
    ); 
}, 

個arrContacts

{ 
    firstName = FirstName Changed; 
    id = 224; 
    lastName = Udaha; 
    phones =   (
        { 
      label = Mobile; 
      value = "123456789"; 
     } 
    ); 
}, 
    { 
    firstName = Chandrananda; 
    id = 225; 
    lastName = ""; 
    phones =   (
        { 
      label = Mobile; 
      value = "345678912"; 
     } 
    ); 
}, 

由於上述兩個數組,我們可以看到兩個變化,第3項被刪除,得到的firstName在第一項改變。

因爲我們可以在通訊錄中包含數千個項目,所以我的問題是,比較這兩個數組並檢測更改的項目(刪除,添加,內部字段更改)的最佳方法是什麼?

一個代碼示例是高度讚賞

+0

你的數據結構幾乎不可能做你想做的事情。你真的需要一本字典的字典,而不是一個字典數組。外部字典應該被鍵入每個聯繫人條目的某種唯一ID。然後你可以通過鍵來關聯這兩個(保存和更改的)字典。然後你可以比較每個相應的內部詞典尋找變化。 – rmaddy

+0

@rmaddy感謝您的想法,高度讚賞,如果你能展示一些例子 – sajaz

+0

從'arrSavedContacts'開始。你有一個字典數組。相反,將所有字典放在字典中而不是數組中。您現有的字典將成爲字典中的值,每個聯繫人的某種唯一ID將成爲其關鍵。現在對'arrContacts'也做同樣的事情。現在,每個聯繫人在兩組數據中將具有相同的唯一ID。 – rmaddy

回答

2

這裏是檢查更改,添加和刪除的代碼。請檢查一下,如果你不明白請評論...

NSMutableArray *oldArr =[NSMutableArray arrayWithArray:@[@{ 
                  @"firstName" : @"Gayan", 
                  @"id" : @224, 
                  @"lastName" : @"Udaha", 
                  @"phones": @[ 
                    @{ 
                     @"label" : @"Mobile", 
                     @"value" : @"123456789" 
                     } 
                    ] 
                  }, 
                 @{ 
                  @"firstName" : @"Chandrananda", 
                  @"id" : @225, 
                  @"lastName" : @"", 
                  @"phones": @[ 
                    @{ 
                     @"label" : @"Mobile", 
                     @"value" : @"234567891" 
                     } 
                    ] 
                  }, 
                 @{ 
                  @"firstName" : @"Joe", 
                  @"id" : @226, 
                  @"lastName" : @"", 
                  @"phones": @[ 
                    @{ 
                     @"label" : @"Mobile", 
                     @"value" : @"345678912" 
                     } 
                    ] 
                  }, 
]]; 

NSMutableArray *newArr =[NSMutableArray arrayWithArray:@[@{ 
                  @"firstName" : @"Gayan", 
                  @"id" : @224, 
                  @"lastName" : @"Udaha", 
                  @"phones": @[ 
                    @{ 
                     @"label" : @"Mobile", 
                     @"value" : @"123456789" 
                     } 
                    ] 
                  }, 
                 @{ 
                  @"firstName" : @"Chandrananda", 
                  @"id" : @225, 
                  @"lastName" : @"", 
                  @"phones": @[ 
                    @{ 
                     @"label" : @"Mobile", 
                     @"value" : @"11111111" 
                     } 
                    ] 
                  }, 
                 @{ 
                  @"firstName" : @"Luan", 
                  @"id" : @229, 
                  @"lastName" : @"", 
                  @"phones": @[ 
                    @{ 
                     @"label" : @"Mobile", 
                     @"value" : @"55555555" 
                     } 
                    ] 
                  }, 
                 ]]; 


NSMutableSet *oldSet = [NSMutableSet setWithArray:oldArr]; 
NSMutableSet *newSet = [NSMutableSet setWithArray:newArr]; 

//1: Get filter all changed, add, delete items 

[oldSet minusSet:newSet]; 
[newSet minusSet:oldSet]; 

NSArray *remainOldArr = [NSArray arrayWithArray:[oldSet allObjects]]; 
NSArray *remainNewArr = [NSArray arrayWithArray:[newSet allObjects]]; 

if (remainNewArr.count == 0 && remainOldArr.count == 0) { 
    // there is no changes. 
    return ; 
} 

//2: detect which items changed,add,delete 

NSMutableArray *arrayChangedItems = nil; 
NSMutableArray *arrayDeleteItems = nil; 
NSMutableArray *arrayAddItems =nil; 

NSPredicate *pre1 = [NSPredicate predicateWithFormat:@"self.id IN %@",[remainOldArr valueForKeyPath:@"id"]]; 
NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"NOT self.id IN %@",[remainOldArr valueForKeyPath:@"id"]]; 
NSPredicate *pre3 = [NSPredicate predicateWithFormat:@"NOT self.id IN %@",[remainNewArr valueForKeyPath:@"id"]]; 

arrayChangedItems = [NSMutableArray arrayWithArray:[remainNewArr filteredArrayUsingPredicate:pre1]]; 
arrayAddItems = [NSMutableArray arrayWithArray:[remainNewArr filteredArrayUsingPredicate:pre2]]; 
arrayDeleteItems = [NSMutableArray arrayWithArray:[remainOldArr filteredArrayUsingPredicate:pre3]]; 
+0

我測試了代碼,但每次都返回arrayAddItems和arrayDeleteItems的空數組。 arrayChangedItems始終是全套物品 – sajaz

+0

超酷的答案。在我的情況下,它需要像這樣稍微改變謂詞。 pre2和pre3應該在使用數組之前進行減號設置操作。此外,相同的數組應該使用filteredArrayUsingPredicate操作 – sajaz

0

在延續到什麼rmaddy建議,是有意義的有字典的字典數據的基礎上唯一的ID首位輕鬆找出缺失。舉例來說,這是你的基地字典應該什麼樣子:現在

{ 224 = { 
     firstName = Gayan; 
     id = 224; 
     lastName = Udaha; 
     phones = (
       { 
       label = Mobile; 
       value = "123456789"; 
       } 
       ); 
     } 

    225 = { 
     firstName = Chandrananda; 
     id = 225; 
     lastName = ""; 
     phones = (
       { 
       label = Mobile; 
       value = "234567891"; 
       } 
       ); 
    } 
} 

,一旦你的數據被正確設定,你可以在NSDictionary添加類別,並實現以下方法:

- (NSArray*)changedKeysIn:(NSDictionary*)iAnotherDict { 
    NSMutableArray *changedKeys = [NSMutableArray array]; 

    for (id key in self) { 
     if(![[self objectForKey:key] isEqual:[iAnotherDict objectForKey:key]]) 
      [changedKeys addObject:key]; 
     } 

     return changedKeys; 
} 

然後,只需調用它像:

[baseDict changedKeysIn:anotherDict]; 
+0

這是一個開始。這僅適用於在這兩個詞典中找到的鍵。邏輯需要添加或刪除一個或其他字典中的密鑰。並且需要添加邏輯以查看更改後的聯繫詞典中發生了什麼變化。 – rmaddy

+0

@rmaddy是的,我設法將數據集作爲字典獲取,每個內部字典使用uniq鍵。 224 = { firstName = Gayan; lastName = Udaha; ( { label = Mobile; value =「1234567890」; } ); };但仍然無法找出檢測內部場變化的邏輯 – sajaz

+0

@sajaz一旦你知道兩個相應的字典是不同的,你將不得不一次比較每個字段。沒有捷徑。 – rmaddy

0

......怎麼

// put new contacts in a dictionary 
NSMutableDictionary *aDictionary = [NSMutableDictionary dictionary]; 
[arrContacts enumerateObjectsUsingBlock:^(id theNewContact, NSUInteger idx, BOOL *stop) 
{ 
    [aDictionary setObject:theNewContact forKey:[theNewContact valueForKey:@"id"]]; 
}]; 

// check each old contact 
[arrSavedContacts enumerateObjectsUsingBlock:^(id theOldContact, NSUInteger idx, BOOL *stop) 
{ 
    NSDictionary *aNewContact = [aDictionary objectForKey:[theOldContact valueForKey:@"id"]]; 
    if (aNewContact == nil) 
    { 
     // delete old contact 
    } 
    else 
    { 
     if (![aNewContact isEqual:theOldContact]) 
     { 
      // update old contact 
     } 
     // remove existing contact from the dictionary 
     [aDictionary removeObjectForKey:[theOldContact valueForKey:@"id"]]; 
    } 
}]; 

// new contacts 
[aDictionary allValues]; 

每個陣列枚舉一次。

相關問題