most effective way of searching using NSPredicate OR statement

烈酒焚心 提交于 2019-12-21 20:23:30

问题


I tried to build a predicate in a previous post, but ended up doing it this way because after 3 hours, I couldn't get it to work.

I feel like there has to be a more effective way, also I need the predicates to be case insensitive.

10,000 cars I have a tire, wheel, seat as three car parts I want to find all cars that have a tire. THEN I want to find all cars that have a wheel. THEN I want to find all cars that have a seat. (I know many will be duplicates, but that's what I need)

Please let me know if there is a more effective way. Also please let me know how to make the predicates case insensitive.

Thank you in advance!

-(NSArray*) loadCarsFromCoreData:(NSMutableArray*)inputCarParts{

    NSMutableArray *totalResults=[[NSMutableArray alloc]init];
    NSFetchRequest *fetchRequest =[[NSFetchRequest alloc]init];

    //To find the cars we are using the car parts
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CarParts" inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSError *error;
    NSMutableArray *predicates =[self parseCarPartsIntoAPredicateArray:inputCarParts];
    for (int i=0; i<[predicates count]; i++) {
        [fetchRequest setPredicate:[predicates objectAtIndex:i]];

        NSArray *records = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
        NSLog(@"results = %i",[records count]);
        [totalResults addObjectsFromArray:records];
    }
    NSLog(@"results = %i",[totalResults count]);
    return [NSArray arrayWithArray:totalResults];
}

-(NSMutableArray*)parseCarPartsIntoAPredicateArray:(NSMutableArray*)inputCarParts{
    NSMutableArray *returnArray=[[NSMutableArray alloc]init];
    for (int i=0; i<[inputCarParts count]; i++) {
        NSPredicate *predicate=[NSPredicate predicateWithFormat:@"partName == %@",[inputCarParts objectAtIndex:i]];
        [returnArray addObject:predicate];
    }

    return returnArray;
}

回答1:


It sounds like what you're really looking for is how to construct a predicate based on an array of possible matches. In that case you'd do something like this:

NSMutableArray *partPredicates = [NSMutableArray arrayWithCapacity:[inputCarParts count]];
for (NSString *partName in inputCarParts) {
    NSPredicate *currentPartPredicate = [NSPredicate predicateWithFormat:@"partName =[c] %@", partName];
    [partPredicates addObject:currentPartPredicate];
}
NSPredicate *fullPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:partPredicates];

The resulting predicate would then be something like partName ==[c] "tire" OR partName ==[c] "wheel" OR partName ==[c] "seat", with one component per array entry. Do one fetch to evaluate them all in one shot.

This will not get duplicate results if you use it in the fetch. You left a comment on the question that indicates you don't want duplicates. If that's the case though, then I'm not sure what I know many will be duplicates, but that's what I need means. It sounds like you wanted the dupes, but you said you didn't.




回答2:


If you need the duplicates, I think you'll have to do 3 separate queries like you're currently doing.

If the duplicates aren't important, you should try creating a compound predicate by using OR between the three predicates you need. The following will find all the cars that either have the specified wheel, tire, or seat:

NSPredicate *predicate=[NSPredicate predicateWithFormat:@"wheelPartName == %@ OR tirePartName == %@ OR seatPartName == %@", wheelPart, tirePart, seatPart];

To make your searches case insensitive, use ==[c] instead of ==, so the predicate in your code would look like:

NSPredicate *predicate=[NSPredicate predicateWithFormat:@"partName ==[c] %@",[inputCarParts objectAtIndex:i]];

Take a look at this reference: String Predicate Programming.



来源:https://stackoverflow.com/questions/14126766/most-effective-way-of-searching-using-nspredicate-or-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!