通过交集和并集合并NSArrays

16

我有两个NSArray,A和B,它们共享一些公共元素,例如:

A: 1,2,3,4,5 
B: 4,5,6,7

我想创建一个新的NSArray,其中包含连接两个NSArrays的内容和第二个NSArray的内容之间的共同内容,同时保留元素的顺序并删除重复项。也就是说,我想要 (A ∩ B) ∪ B。

对先前的NSArrays进行的操作将产生以下结果:

A ∩ B: 4,5
(A ∩ B) ∪ B: 4,5,6,7

如何在Objective-C中实现这个?


1
假设您想要比这更合理的内容,但 (A ∩ B) ∪ B 确实没有太多意义:它只是 B。 - galactica
5个回答

25

NSArray转换为NSSet,可以使用标准的集合操作。

NSArray *a = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
NSArray *b = [NSArray arrayWithObjects:@"4", @"5", @"6", @"7", nil];

NSMutableSet *setA = [NSMutableSet setWithArray:a];
NSSet *setB = [NSSet setWithArray:b];
[setA intersectSet:setB];
NSLog(@"c: %@", [setA allObjects]);

NSLog输出: c: (4, 5)

[setA unionSet:setB];
NSLog(@"d: %@", [setA allObjects]);

NSLog输出:d: (6, 4, 7, 5)


15

如其他人所建议,您可以轻松地使用NSSet 来实现,但这样做将不会保留顺序。

如果您想要保留顺序并且目标系统是OS X 10.7+,那么您可以使用新的NSOrderedSet(以及可变的子类)来完成同样的事情。


大多数人似乎忽略了保留顺序的重要方面,这排除了NSSet。我的目标是iOS 4.3,它似乎没有NSOrderedSet库。还有其他想法吗? - Mat Kelly
@Mat 使用 NSSet 方法,但是需要手动从 B 中提取最终集合中的元素。你需要自己保留顺序。 - Dave DeLong
2
@Mat 我也想指出 "(A 交 B) 并 B" 总是会得到 "B" 的结果。 - Dave DeLong
Dave,你是正确的,我在实现时意识到了这一点。我的想法是那些只属于B的元素。我相信这可以用 NOT(A并集B)交 NOT(B)来表示。这样表示我的想法正确吗?感谢你的纠正! - Mat Kelly
Dave,我理解你的意思,但使用交集和并集符号会有什么等效的表示呢? - Mat Kelly
显示剩余3条评论

6
通过使用NSSet,正如其他人指出的那样。对于...
NSArray * a = [NSArray arrayWithObjects: ... ];
NSArray * b = [NSArray arratWithObjects: ... ];
NSMutableSet * set = [NSMutableSet setWithArray:a];
[set intersectSet:[NSSet setWithArray:b];
[set unionSet:[NSSet setWithArray:b];

这样处理可以去重,但不会保留顺序。你需要将“set”中的结果排序并放回到数组中。没有本地集合功能可以完成所有操作——如果你想保留顺序并单独考虑重复项,请使用NSMutableArray的 -removeObjectsInArray:方法等。

2

(A ∩ B) ∪ B总是返回B,所以计算这个是一件很奇怪的事情。这就像说“给我所有绿色车辆的集合,再加上所有车辆的集合”。这将会给你所有车辆的集合。


0

你可以使用 NSSet 类来执行这些操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接