Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何根据对象的属性比较两个NSSET?_Iphone_Objective C_Ios_Ipad_Nsset - Fatal编程技术网

Iphone 如何根据对象的属性比较两个NSSET?

Iphone 如何根据对象的属性比较两个NSSET?,iphone,objective-c,ios,ipad,nsset,Iphone,Objective C,Ios,Ipad,Nsset,我有两套 nsset1: person.id = 1, person.id = 2, person.id = 3 nsset2: person.id = 1, person.id = 2 结果应该是: nsset1 - nsset2: person (with id 3) nsset2 - nsset1: null 这两个集合中具有相同id的对象是不同的对象,所以我不能简单地进行设置 我想做一些类似的事情: nsset1: person.id = 1, person.id = 2, pers

我有两套

nsset1: person.id = 1, person.id = 2, person.id = 3
nsset2: person.id = 1, person.id = 2
结果应该是:

nsset1 - nsset2: person (with id 3)
nsset2 - nsset1: null
这两个集合中具有相同id的对象是不同的对象,所以我不能简单地进行设置

我想做一些类似的事情:

nsset1: person.id = 1, person.id = 2, person.id = 3
nsset2: person.id = 4, person.id = 5
结果应该是这样的:

nsset1 - nsset2: person (id 1), person (id 2), person (id 3)
nsset2 - nsset1: person (id 4), person (id 5)

最好的方法是什么?

你应该试试这样的方法

NSSet* nsset1 = [NSSet setWithObjects:person_with_id_1, person_with_id_2, person_with_id_3, nil];
NSSet* nsset2 = [NSSet setWithObjects:person_with_id_2, person_with_id_4, nil];

// retrieve the IDs of the objects in nsset2
NSSet* nsset2_ids = [nsset2 valueForKey:@"objectID"]; 
// only keep the objects of nsset1 whose 'id' are not in nsset2_ids
NSSet* nsset1_minus_nsset2 = [nsset1 filteredSetUsingPredicate:
    [NSPredicate predicateWithFormat:@"NOT objectID IN %@",nsset2_ids]];

@AliSoftware的答案是一种有趣的方法
NSPredicate
在核心数据之外非常慢,但这通常是可以的。如果性能有问题,您可以使用循环实现相同的算法,这需要多出几行代码,但通常更快

另一种方法是询问是否应始终将具有相同ID的两个人视为同等身份。如果这是真的,那么您可以像这样覆盖person类的
isEqual:
hash
(假设
identifier
是一个整数):

这样做,所有
NSSet
操作都会将具有相同标识符的对象视为相等对象,因此您可以使用
minuset
。另外,
NSMutableSet addObject:
将在标识符上自动为您唯一


实现
isEqual:
hash
具有广泛的影响,因此您需要确保每次遇到具有相同标识符的两个person对象时,它们都应被视为相等的。但是如果你是这样的话,这确实大大简化和加速了你的代码。

这看起来很好,但我得到了一个类似于
的错误原因:'无法解析格式字符串“objectID NOT IN%@”
我使用了
objectID
,因为这是这个对象属性的真实名称。过滤之前的一切看起来都很好,我得到了ID等等。知道吗?是的,对不起,我之前没有测试我的答案。声明
NOT
运算符应用于整个表达式(而不是像
IN
运算符那样的另一个运算符),因此我们应该在%@中写入
NOT objectID,而不是在%@
中写入
objectID。我相应地更新了我的答案。
- (BOOL)isEqual:(id)other {
  if ([other isMemberOfClass:[self class]) {
    return ([other identifier] == [self identifier]);
  }
  return NO;
}

- (NSUInteger)hash {
  return [self identifier];
}