我正在使用谓词搜索与任何其他用户具有相同首选项的用户
用户<< - >>首
鉴于以下状态;我想检查一个新的注册用户
(Sam, nickname: "foo", language: "english")
查看是否有任何现有用户具有相同的首选项。可以有任意数量的偏好类型。在这种情况下,它会检测到Sally具有相同的选择
用户
| Name |
| Sally |
| John |
PreferenceTypes
| Name |
| nickname |
| language |
| .... |
使用UserPreferences
User PreferenceTypes Selection
Sally | nickname | "foo"
Sally | language | "english"
John | nickname | "bar"
John | language | "english"
答案 0 :(得分:1)
这是您设置模型的方法:
User <---->> Preference <<-----> PreferenceType
User.name // name string
User.preferences // to-many to Preference
Preference.value // the value, or "selection"
Preference.user // to-one to User
Preference.type // to-one to PreferenceType
Preference.name // name of preference, such as "language"
PreferenceType.preferences // to-many relationship to Preference
您的谓词需要一个子查询,并且在资源使用方面会非常“昂贵”。我假设允许一些用户具有其他用户没有的偏好,即,当我们知道可能的偏好的总数时,我们不知道一个特定用户具有的偏好的数量。我无法从头脑中写出这个问题,我不得不考虑一下。 ---任何人?
一种实用的方法是首先获取用户的子集,例如具有完全相同昵称的用户。使用如下谓词获取首选项对象会更简单:
[NSPredicate predicateWithFormat:
@"type.name = 'nickname' && value = %@ && not (user = %@)", userNickname, user];
在小的用户子集上(由foundPreference.user
引用),您可以运行您编写的自定义方法(hasSamePreferences
),您可以在其中迭代首选项并检查是否存在和相等。
-(BOOL)hasSamePreferencesAsUser:(User*)otherUser {
NSSet *myPreferenceKeys = [self.preferences valueForKeyPath:@"type.name"];
NSSet *otherPreferenceKeys = [otherUser.preferences valueForKeyPath:@"type.name"];
if (myPreferenceKeys.count != otherPreferenceKeys.count) {
return NO;
}
for (NSString *key in myPreferenceKeys) {
if (![otherPreferenceKeys containsObject:key]) {
return NO;
}
NSPredicate *keyFilter = [NSPredicate predicateWithFormat:@"type.name = %@", key];
// String only for demonstration
NSString *myValue = [self.preferences
filteredArrayUsingPredicate:keyFilter].firstObject;
NSString *otherValue = [otherUser.preferences
filteredArrayUsingPredicate:keyFilter].firstObject;
if (![myValue isEqualToString:otherValue]) {
return NO;
}
}
return YES;
}
顺便说一句,如果你不期望超过20个首选项,它会更加务实,并将这些首选项硬编码为User
(或Settings
实体的正确命名属性如果你愿意,一对一的关系)。您的代码将非常易读,您的谓词相当简单。
答案 1 :(得分:0)
如果你想检查昵称是否已经存在,你可以尝试这样的事情(如果我理解你的模型是正确的)
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"UserPreferences"
inManagedObjectContext:context]];
[NSPredicate predicateWithFormat:@"Selection == %@ AND PreferenceTypes == 'nickname'", newUser.nickname]
NSArray *ary = [context executeFetchRequest:fetchRequest error:&err];
if(ary && ary.count > 0)
{
// handle "user exists" case
}
else
{
// handle "create user" case
}
我希望那就是你在寻找的东西。如果我理解你的问题是错误的或不起作用,请告诉我;)