Nsarray with Nspredicate Using Not In

NSArray with NSPredicate using NOT IN

What about NOT (CategoryID IN %@)?

Using NSPredicate to filter an NSArray of objects based on a property which is an NSDictionary

You don't provide any code about you're using NSPredicate, so I wrote a simple example. Maybe this will help you.

@objc class Dummy: NSObject {
let propertyOne: Int = 1
let propertyTwo: Int = 1
let propertyThree: NSDictionary

init(dict: NSDictionary) {
propertyThree = dict
super.init()
}
}

let arr: NSArray = [
Dummy(dict: ["keyOne" : "one"]),
Dummy(dict: ["keyOne" : "two"]),
Dummy(dict: ["keyOne" : "three"]),
Dummy(dict: ["keyOne" : "one"]),
Dummy(dict: ["keyOne" : "five"])
]

let predicate = NSPredicate(format: "SELF.propertyThree.keyOne == 'one'")
let results = arr.filteredArrayUsingPredicate(predicate)
print(results)

Filter NSArray based on another array using predicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"not (self.username IN %@)", [some_usernames valueForKey:@"username"]];
NSArray *remaining_usernames = [all_usernames filteredArrayUsingPredicate:predicate];

complete example

@interface Alpha : NSObject
@property (nonatomic, copy) NSString *username;
-(instancetype) initWithUsername:(NSString *)username;
@end

@implementation Alpha
-(instancetype) initWithUsername:(NSString *)username
{
self = [super init];
if (self) {
self.username = username;
}
return self;
}

-(NSString *)description{
return [NSString stringWithFormat:@"%@: %@", NSStringFromClass([self class]), self.username];
}
@end

NSArray *all_usernames = @[[[Alpha alloc] initWithUsername:@"a"], [[Alpha alloc] initWithUsername:@"b"], [[Alpha alloc] initWithUsername:@"z"], [[Alpha alloc] initWithUsername:@"f"], [[Alpha alloc] initWithUsername:@"e"]];
NSArray *some_usernames = @[[[Alpha alloc] initWithUsername:@"b"], [[Alpha alloc] initWithUsername:@"f"]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"not (self.username IN %@)", [some_usernames valueForKey:@"username"]];
NSArray *remaining_usernames = [all_usernames filteredArrayUsingPredicate:predicate];

NSLog(@"%@", remaining_usernames);

prints

(
"Alpha: a",
"Alpha: z",
"Alpha: e"
)

Using NSPredicate to find elements in an NSArray similar to SQL WHERE IN clause

You can use NSCompoundPredicate to merge together various NSPredicate objects like this:

NSMutableArray *predicates = [NSMutableArray array];

[predicates addObject:[NSPredicate predicateWithFormat:@"tag == %@", @"iphone"]]];
[predicates addObject:[NSPredicate predicateWithFormat:@"tag == %@", @"apple"]]];
[predicates addObject:[NSPredicate predicateWithFormat:@"tag == %@", @"music"]]];

//Create a predicate using AND
NSPredicate *compoundANDpred = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];

//Create a predicate using OR
NSPredicate *compoundORpred = [NSCompoundPredicate orPredicateWithSubpredicates:predicates];

or you could use a predicate with ANY and IN, as outlined in some of the other answers.

Filtering a large NSArray with NSPredicate

Solving this problem is easy if you iterate the array yourself using a block predicate. At some point a formatted NSPredicate would have to boil down to this, so there shouldn't be much of a performance hit. -[NSString rangeOfString:] can be used to test for inclusion of the string.

return [_words filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL (id evaluatedString, NSDictionary *bindings) {
return string.length > 2 && [string rangeOfString:evaluatedString].location != NSNotFound;
}]];

Filter NSArray with NSPredicate inexact/similar match?

You have two problems (a) the match is wrong and (b) you have nested arrays.

(a) [cd] means ignore case and diacritics, not punctuation and whitespace. A solution here is to use a regular expression and MATCHES[CD] as the predicate. You need a regular expression which will match the terms you are looking for. A basic re is:

@"fullmetal[^a-z]*alchemist[^a-z]*brotherhood"

where [^a-z]* matches zero or more (*) characters from the set [...] of every character which is not (^) a letter a-z.

While this works it probably matches far more than you wish - you should refine the regular expression.

(b) The error you got Can't do regex matching on object... is because you cannot match a regular expression against an array, and the elements of your array are themselves array. You can address this using a simple loop over the elements, something along the lines of:

NSMutableArray *filtered = [NSMutableArray new];                                          // allocate an empty mutable array in which to accumulate the matches
for(NSArray *subArray in arraytoEvaluate) // loop over each sub array
[filtered addObjectsFromArray:[subArray filteredArrayUsingPredicate: titlePredicate]]; // and perform the predicate

HTH

NSArray filterArrayUsingPredicate never returning/ blocking execution

Change to this :

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == 'CNN'"];

In predicates, you must use query languages, in this case is a string literal: in Query languages two options: 'stringLitareal' or "stringLiteral" but this second don´t work because " is used in objective-C, you need to scape the ", that´s it: name == \"CNN\". You can test this, is the same:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == \"CNN\""];

More Info: https://developers.google.com/chart/interactive/docs/querylanguage#literals

Parentheses is not a problem (Query language). This also work : @"(name == 'CNN')"

Using NSPredicate to filter an NSMutableArray of NSDictionaries to find if a key exists

A dictionary delivers nil as value for absent key. So simply compare the key against nil.

NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K==NULL", key]; // Dictionaries not having the key
NSPredicate *predicateString = [NSPredicate predicateWithFormat:@"%K!=NULL", key]; // Dictionaries having the key

Using NSPredicate to filter NSArray and find similar strings

What you are looking for is a custom predicate which uses a bounded Levenshtein Distance to filter out words that are sufficiently different from a target word.

Assuming you use an implementation of Levenshtein Distance as found in this gist, your code will look approximately like this:

NSPredicate *distancePredicate = [NSPredicate predicateWithBlock:^(NSString *name, NSDictionary<NSString *, id> *bindings) {
// key is the string you're looking for (e.g. 'nink')
NSString *key = bindings[@"key"];

// Calculate the Levenshtein Distance. This may be different depending
// on how you implement it. You may want to weight matchGain and
// missingCost differently.
NSInteger score = [key compareWithWord:name matchGain:0 missingCost:1];

// Only include words that are "close enough", i.e. within two a letter
// difference.
return (BOOL)(score < 2);
}];

This predicate defines a general predicate "template", which you can then use to filter the array with the actual string you're looking for:

    NSDictionary<NSString *, id> *bindings = @{@"key": @"Nink"};
NSMutableArray *array = [NSMutableArray arrayWithObjects:@"Nick", @"Ben", @"Adam", @"Melissa", nil];
NSIndexSet *indices = [array indexesOfObjectsPassingTest:^(id object, NSUInteger index, BOOL *stop) {
return [distancePredicate evaluateWithObject:object substitutionVariables:bindings];
}];

NSArray *results = [array objectsAtIndexes:indices];

BTW, there is nothing special about the word @"key"; you can change that to be any string identifying the substitution (e.g. @"name", @"term", etc., are all valid). The key you provide in the substitution variables is the key you should use to retrieve the value.



Related Topics



Leave a reply



Submit