Objective-C NSPredicate Binding

All,

I'm trying to use predicates to get the returned search back, prioritizing rows that start with the VS search string. just contained in it.

For example, if the search string was "Objective-C", I want to return the filtering results like this:

Objective-C a Primer
Objective-C Objective-C Patterns
Programming
All About Objective-C
How to Program in Objective-C

Here's what I've tried, but since it's OR, it clearly doesn't give priority to the first condition. Is there a way to do chaining with predicates? Thanks to

  NSPredicate *filter = [NSPredicate predicateWithFormat:@"subject BEGINSWITH [cd] %@ OR subject CONTAINS [cd]", searchText,searchText];
  NSArray *filtered = [myArray filteredArrayUsingPredicate: filter];

      

+3


source to share


2 answers


I don't think there is a way to do it with NSPredicate on its own. The sorted results you seem to be asking for. You do this by sorting the results after you return them from the predicate. In this case, since the sort order is not just an alphabet, you must use the NSArray method -sortedArrayUsingComparator:

. Something like this (untested, printed on top of my head).



NSArray *sortedStrings = [filtered sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSString *string1 = (NSString *)obj1;
    NSString *string2 = (NSString *)obj2;
    NSUInteger searchStringLocation1 = [string1 rangeOfString:searchString].location;
    NSUInteger searchStringLocation2 = [string2 rangeOfString:searchString].location;
    if (searchStringLocation1 < searchStringLocation2) return NSOrderedDescending;
    if (searchStringLocation1 > searchStringLocation2) return NSOrderedAscending;
    return NSOrderedSame;
}];

      

+1


source


It looks like you are trying to sort the array using a predicate, or trying to filter AND sort using just the predicate. Predicates return boolean values: either the string starts, contains the search text, or not. Predicates don't tell you anything about relative order. Filtering the array removes those objects for which the predicate you supply returns NO, so the filtered array will only contain objects that start with or contain the search text. Indeed, since any string that begins with the search text also contains it, you can simplify your predicate to only the "contains" part.



If you want to change the order of the filtered results, sort the filtered array with the appropriate comparator.

+1


source







All Articles