LoginSignup
0
0

More than 5 years have passed since last update.

取得兩個 NSArray 的 Diff

Last updated at Posted at 2015-05-07

前幾天被問到如何取得兩個 array 的差集合,

舉例來說,有 array A, B 各為下

a = [1, 3, 4]
b = [2, 3, 4]

就會取得一個 diff array

diff = [1, 2]

NSArray 也沒有直接就可以取得差集的 API ,只有 NSMutableArrayremoveObjectsInArray ,但是這又只能對一個 array 移除和另外一個 array 有重複的物件。

這時候的解法就會是

  1. 先取得各自的差集
  2. 再把差集合併起來
NSArray *numbersA = @[@1, @3, @4];
NSArray *numbersB = @[@2, @3, @4];

NSMutableArray *diff = [NSMutableArray array];
NSMutableArray *diffA = [numbersA mutableCopy];
[diffA removeObjectsInArray:numbersB];
NSMutableArray *diffB = [numbersB mutableCopy];
[diffB removeObjectsInArray:numbersA];

[diff addObjectsFromArray:diffA];
[diff addObjectsFromArray:diffB];

這時候的 diff 就會是兩者個別差集後合併起來的陣列

用 NSMutableSet 做集合運算

接著找了找,找到一篇文章,用 NSMutableSet 的 intersect 和 minus 兩個 methods 可以來做交集合和集合相減。

運算邏輯

於是這個運算會分成三個步驟

  1. 將兩個 arrays 合併成一個 NSMutableSet
  2. 找出兩個 arrays 中有重複的元素
  3. 將合併的 set 移除重複的元素
  4. 轉換回 NSArray

解法

一樣先創建兩個 arrays

NSArray *numbersA = @[@1, @3, @4];
NSArray *numbersB = @[@2, @3, @4];

接著把邏輯實作出來:

// 合併兩個 arrays
NSMutableSet *numbersSet = [NSMutableSet setWithArray:numbersA];
[numbersSet addObjectsFromArray:numbersB];

// 找出兩者皆有的元素
NSMutableSet *duplicatedSet = [NSMutableSet setWithArray:numbersA];
[duplicatedSet intersectSet:[NSSet setWithArray:numbersB]];

// 減掉重複的元素
[numbersSet minusSet:duplicatedSet];

// 轉換回 array
NSArray *diff = [numbersSet allObjects];

排序

NSSet 本身並沒有將元素排序,將 array 轉換成 set 之後,原本的順序就會亂掉。
因此,上一節所得的結果,可能會是 [1,2] ,也有可能是 [2,1] 。

如果想要排序,就可以改用 NSMutableOrderedSet 和相關的 methods :

NSMutableOrderedSet *numbersSet = [NSMutableOrderedSet orderedSetWithArray:numbersA];
[numbersSet addObjectsFromArray:numbersB];

NSMutableOrderedSet *duplicatedSet = [NSMutableOrderedSet orderedSetWithArray:numbersA];
[duplicatedSet intersectOrderedSet:[NSOrderedSet orderedSetWithArray:numbersB]];

[numbersSet minusOrderedSet:duplicatedSet];

感想

現在雖然知道解法,不過還不太清楚,單純使用 array 運算和使用 NSSet 做集合運算的優缺點在哪裡。
目前看 NSSet 的方式雖然要先轉換型態,但是覺得這個邏輯寫起來還比前者漂亮、容易理解。

【更新】
單純使用 array 的方法沒有繞一圈跑去用 NSSet 處理後再轉回來成 array ,看起來也比較直接,說不定我會比較喜歡這個 :flushed:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0