Filtering NSMutableArray with NSPredicate and regex - ios

I have a NSMutableArray containing NSString.
I need to filter only the objects that begins with (^WS|WV)[A-Z]{2}[0-9]{2}
How can I do it with NSPredicate?
Assuming that the array is called myArray, how can I write it?

Just google it to see a lot of answers like this:
NSArray *array = #[#"WSPS01", #"WLP05", #"1112"];
NSString *regex = #"(^WS|WV)[A-Z]{2}[0-9]{2}";
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
NSArray *filteredArray = [array filteredArrayUsingPredicate:pred];
// filteredArray contains only WSPS01
array - its your NSMutableArray

Solved.
this is the correct regex:
NSString *regex = #"(^WS|WV|WC)[A-Z]{2}[0-9]{2}.*"
The only question that I still have is why the MATCHES operator works and the BEGINSWITH not...

Related

Filter NSArray of Arrays by One Element of Array Using NSPredicate in IOS

It is possible to filter an array of strings as follows:
NSArray *array = #[#"honda",#"toyota",#"ford"];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#",#"ford"];
NSArray *filtered = [array filteredArrayUsingPredicate:pred];
I want to search an array that contains arrays of two strings by the values for the first of the strings. So for:
NSArray *cars = #[#[#"honda",#"accord"],#[#"toyota",#"corolla"],#[#"ford",#"explorer"]];
I want to search the first dimension (honda, toyota, ford) for #"ford"
Is there a way to tell the predicate I want to search on only the first attribute and return matching elements of the array?
Well here is the pred you need.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF[FIRST] contains[cd] %#", #"ford"];

NSPredicate on NSArray of NSDictionary

Imagine you have the following structure for an NSArray of NSDictionary objects:
#define kFlameText #"text"
#define kFlameRelation #"relation"
NSArray* data = #[#{kFlameText:#"TextFlame1", kFlameRelation:#"Relation1"}, #{kFlameText:#"TextFlame2", kFlameRelation:#"Relation2"}, #{kFlameText:#"TextFlame3", kFlameRelation:#"Relation3"}}
You want to use a NSPredicate to extract the dictionary located in second position in your NSArray of NSDictionary based on the NSString #"Relation2"
You tried multiple times, with you last attempt being:
NSPredicate* sortFlames = [NSPredicate predicateWithFormat:#"SELF contains[cd] %#", #"Relation2"];
But you are still not there, you still get the following error message:
How would you make it work?
This predicate should do the trick:
NSPredicate *sortFlames = [NSPredicate predicateWithFormat:#"SELF.%K CONTAINS[cd] %#", kFlameRelation, #"Relation2"];
The %K is for the dynamic property name, more info here.

NSPredicate not filtering as desired

Consider the following array:
NSArray *dataValues = #[#"Foo[0]", #"Foo[1].bar"];
And the following regex pattern, predicate and expected output:
NSString *pattern = #"Foo[0]";
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"SELF BEGINSWITH[cd] %#", pattern];
NSArray *results = [dataValues filteredArrayUsingPredicate: predicate];
NSLog(#"matches = %ld", (long)results.count);
This prints 1 in the console as expected. If we change the pattern to:
NSString *pattern = #"Foo\\[[0-9]\\]";
I would expect this to print 2 in the console, but it prints 0. I have double escaped the outer square brackets to allow them to be parsed and expect to find strings that have the numbers 0 to 9 inside the brackets to match this expression.
I have checked the regex against the following site, which does work correctly:
http://regexr.com/3bcut
I have no warnings/errors in Xcode (6.4, 6E35b) running against the iOS 8.4 iPhone 6 Plus simulator, but why does my regex not filter as expected?
You could try this depending on what your needs are:
NSArray *dataValues = #[#"Foo[0]", #"Foo[1].bar"];
NSString *pattern = #"Foo[*]*";
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"SELF LIKE %#", pattern];
NSArray *results = [dataValues filteredArrayUsingPredicate: predicate];
NSLog(#"matches = %ld", (long)results.count);
You could go a little more basic and use
NSMutableArray *results = [NSMutableArray array];
for (NSString *str in dataValues) {
if ([str rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound) {
if ([str hasPrefix:#"Foo["]) {
[results addObject:str];
}
}
}
NSLog(#"matches = %ld", (long)results.count);
After raising a TSI with Apple (well, who uses those things anyway?) they said I simply needed to use MATCHES instead of BEGINSWITH, which is only used for string matching - whereas I am trying to match on a regex.
My predicate should have therefore read:
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"SELF MATCHES[cd] %#", pattern];

Using predicate to find if string value exists

I have a NSMutableArray of objects with tag attributes assigned to them. I am trying to find if any of these objects have a tag assigned to them of the string value "a".
my code so far:
for (Object *object in self.array)
{
NSDictionary *attrs = [object propertyValue:#"attrs"];
NSString *tag = attrs[#"tag"];
}
Can I do something like:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"a"];
NSArray *results = [self.array filteredArrayUsingPredicate:predicate];
not sure how it works?
Try this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"tag == %#", #"a"];
NSArray *result = [NSMutableArray arrayWithArray:[self.array filteredArrayUsingPredicate:predicate]];
Use 'contains[c]' instead of '==' if you want to perform case-insensitive search.
If you want to filter for any other property, replace 'tag' with that property name.
You will need to do something more like :
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.property_name contains[c] '%#'", #"a"];
NSArray *result = [NSMutableArray arrayWithArray:[self.array filteredArrayUsingPredicate:predicate]];

String search in string array in objective c

I want to search a specific string in the array of strings in objective c. Can somebody help me in this regard?
BOOL isTheObjectThere = [myArray containsObject: #"my string"];
or if you need to know where it is
NSUInteger indexOfTheObject = [myArray indexOfObject: #"my string"];
I strongly recommend you read the documentation on NSArray. It's best to do that before posting your question :-)
You can use NSPredicate class for searching strings in array of strings.
See the below sample code.
NSMutableArray *cars = [NSMutableArray arrayWithObjects:#"Maruthi",#"Hyundai", #"Ford", #"Benz", #"BMW",#"Toyota",nil];
NSString *stringToSearch = #"i";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",stringToSearch]; // if you need case sensitive search avoid '[c]' in the predicate
NSArray *results = [cars filteredArrayUsingPredicate:predicate];
This is the most efficient way for searching strings in array of strings
NSMutableArray *cars = [NSMutableArray arrayWithObjects:#"Max",#"Hai", #"Fine", #"Bow", #"Bomb",#"Toy",nil];
NSString *searchText = #"i";
NSArray *results = [cars filteredArrayUsingPredicate:predicate];
// if you need case sensitive search avoid '[c]' in the predicate
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"title contains[c] %#",
searchText];
searchResults = [cars filteredArrayUsingPredicate:resultPredicate];

Resources