Iphone 使用NSPredicate在两个数组中匹配id

Iphone 使用NSPredicate在两个数组中匹配id,iphone,objective-c,nspredicate,Iphone,Objective C,Nspredicate,你好,我有一个可能很简单的问题,但我还不能处理它 我有一个Modelclass“Location”,它包含一个类别ID为12、23、56的数组。 然后我有一个数组,其中包含所有可用类别ID的1,2,3,4,5,6,7,。。。 所有这些类别都有一个ID,并显示在TableView中,并且可以选择或不选择。 我在MapView注释类is Location上显示了一系列标记,这些标记应该根据所提到的过滤器TableView中过滤器的选择来显示。 我需要实现一个“按类别过滤”功能,删除所有标记并再次添加

你好,我有一个可能很简单的问题,但我还不能处理它

我有一个Modelclass“Location”,它包含一个类别ID为12、23、56的数组。 然后我有一个数组,其中包含所有可用类别ID的1,2,3,4,5,6,7,。。。 所有这些类别都有一个ID,并显示在TableView中,并且可以选择或不选择。 我在MapView注释类is Location上显示了一系列标记,这些标记应该根据所提到的过滤器TableView中过滤器的选择来显示。 我需要实现一个“按类别过滤”功能,删除所有标记并再次添加,但仅基于列表中的选择

因此,我需要将位置模型中带有过滤器id的数组与TableView中带有所有过滤器id的数组进行比较。我为此使用了以下函数:

for (Location *currLocation in arrListOfLocationsNearby) {
对于currLocation.arrKatIds中的NSString*currKatId{

NSInteger intCurrKatId = [currKatId integerValue];
NSLog(@"Current KatId %@ id: %d \n", currLocation.strAdr, intCurrKatId);

for (Filter *currFilter in [SDM getSharedDataManager].arrListOfFilterOptions) {

 if (currFilter.isSelected) {

  NSInteger intCurrFilterId = [currFilter.strAtt_id intValue];
  NSLog(@"Current Filter %@ id: %d \n", currFilter.strAtt_text, intCurrFilterId);

  if ([currKatId intValue] == [currFilter.strAtt_id intValue]) {
   currLocation.isVisible = YES;
  }else {
   currLocation.isVisible = NO;
  }
 }
}
} }

我知道这将是最无效的循环方式。我想用NSPredicate来解决这个问题,但我以前从未用过,也找不到解决我问题的例子

你们有什么提示吗


关于m.

尝试为每个测试使用字符串表示:

NSArray *arrayOfPredicateStrings = ;// array of all tests, probably [SDM sharedDataManager].arrListOfFilterOptions

NSPredicate *enabled = [NSPredicate predicateWithFormat:@"isSelected == true"];

NSArray *arrayOfEnabledPredicateStrings = 
        [arrayOfPredicateStrings filteredArrayUsingPredicate:enabled];

NSMutableString *formatString;
BOOL firstTime = YES;
for (NSString *string in arrayOfEnabledPredicateStrings) { 
    // Concatinate strings with OR inbetween
    if (firstTime) {
        firstTime = NO;
        formatString = [string mutableCopy];
    } else {
        [formatString appendFormat:@" OR %@", string]; 
    }
} // formatString should look something like @"ivar1 >= 1 OR ivar2 == true OR ivar3 != \"Hello, World\""
NSPredicate *predicate = [NSPredicate predicateWithFormat:string];

NSArray *arrListOfLocationsNearby; // assume already filled

NSArray *suitableNearbyLocations = 
        [arrListOfLocationsNearby filteredArrayUsingPrediacate:predicate];
如果您的SDM类后面有CoreData数据存储,只需创建如下的获取请求:

NSPredicate *predicate = ;// get the predicate as above
NSManagedObjectContext  *context = ;// a managed object context
NSEntityDescription *entity = 
        [NSEntityDescription entityForName:@"entityName" inManagedObjectContext:context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entity;
request.predicate = predicate;

NSError *error;
NSArray *results = [context executeFetchRequest:request error:&error];
[request release];

可以找到谓词格式语法和用法

所以每个位置对象都有许多categoryId?是否要显示在ArrayOfEnabledCategoryId中具有categoryID的任何位置对象

假设您有一个位置实体和一个CategoryID实体,并且它们之间存在多对多关系位置类别,则可以执行以下操作:

NSArray * arrayOfEnabledCategoryIDs = ...; //these are the categories to display
NSFetchRequest * f = [[NSFetchRequest alloc] init];
[f setEntity:theEntityDescriptionForLocationObjects];
[f setPredicate:[NSPredicate predicateWithFormat:@"ANY categories.categoryID IN %@", arrayOfEnabledCategoryIDs]];

如果您熟悉RubyonRails中的ActiveRecord。我一直在使用一个名为activerecord+fetching+for+core的很棒的库,您可以在这里找到更多关于它的信息


它确实清理了我的代码。

我开始回答,感到困惑,但现在我想我又明白了。基本上,您有三个数组:一个包含所有类别,一个包含用户在tableview中选择的类别,还有一个…-不,又困惑了。
NSArray *departments = [NSArray arrayWithObjects:dept1, dept2, ..., nil];
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];

NSArray *people = [Person findAllWithPredicate:peopleFilter];