I've a person object which has NSString properties firstname, lastname, birthday, and NSMutableDictionary of different phone numbers of that person.
I've added different person objects in an NSMutableArray named personArray.
Try using this method on NSArray. Something like this:
return [personArray[[personArray indexOfObjectPassingTest:^ (id obj, NSUInteger index, BOOL stop) {
return [lastName isEqualToString:[obj lastName]];
}]] phoneNumber];
You get the idea.
You should be able to do it like this:
-(NSArray *) phoneNumberFor:(NSString *)lastName{
NSInteger indx = [self.personArray indexOfObjectPassingTest:^BOOL(Person *aPerson, NSUInteger idx, BOOL *stop) {
return [aPerson.lastname isEqualToString:lastName];
}];
if (indx != NSNotFound) {
return [self.personArray[indx] phoneNumbers].allValues;
}else{
return nil;
}
}
In this example, I'm assuming an array property called personArray, a class name of "Person" for your person objects, and a mutable dictionary called phoneNumbers. I'm also assuming that the dictionary contains several keys and values, where all of the values are phone numbers.
You can get object from array of the given lastname like as follow:-
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"lastname == '%#'", lastname];
NSArray *foundPersonArray = [personArray filteredArrayUsingPredicate:predicate];
NSLog("found person object = %#",foundPersonArray);
But if you want to search multiple object of same lastname from array then you can do following:-
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"lastname LIKE[c] %#", lastname];
NSArray *foundPersonArray = [personArray filteredArrayUsingPredicate:predicate];
NSLog("found person object = %#",foundPersonArray);
Related
My NSMutableArray contains some strings as elements. One of the element is repeated many times at different indexes in the array. For example [#"", #"1,2,3",#"",#"5,3,2,1",#""].
I want to remove all the elements with value #"" from the mutable array. I tried following ways but couldn't get the solution.
Using For loop:
for(id obj in myMutableArray)
{
if([obj isEqualToString:#""])
{
[myMytableArray removeObject:obj];
}
}
Using dummy mutable array called nextMutableArray
for(id obj in myMutableArray)
{
if([obj isEqualToString:#""])
{
continue;
}
else [nextMutableArray addObject:obj];
}
In both the ways, elements (#"") at other indexes are removed but not at the index 0 (first object). What could be the possible reason? Is there any way to remove all the elements that contain string #"" from the mutable array?
one option is to filter your array using predicates:
NSArray *someArray = #[#"", #"1,2,3", #"", #"5,3,2,1", #""];
NSLog(#"%#", someArray);
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF != ''"];
NSArray *filteredArray = [someArray filteredArrayUsingPredicate:predicate];
NSLog(#"%#", filteredArray);
No Need of For loop. Simply use this.
[mutableArray removeObjectIdenticalTo:#""];
If you want to remove duplicate entries from an array, You can use NSSet Class.
NSSet did not accept duplicate/s value.
NSMutableArray *arrTest=[[NSMutableArray alloc]initWithObjects:#"", #"1,2,3",#"",#"5,3,2,1",#"", nil];
NSSet *set = [NSSet setWithArray:arrTest];
arrTest = [[set allObjects] mutableCopy];
or
You can do like this:
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id str, NSDictionary *unused) { return ![str isEqualToString:#""]; }];
arrTest = [[arrTest filteredArrayUsingPredicate:predicate]mutableCopy];
This is fast and simple way.
I have two arrays and I'm trying to filter the first (array1) with a matching property that exists in a second array (array2). The first array is a dictionary array with key 'name'. The second array is an array of objects with property 'name'. Is it possible to filter contents of 'array1' and display only those that have a matching 'name' found in 'array2'?
I've tried:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name == #%",self.array2];
NSArray *results = [array1 filteredArrayUsingPredicate:pred];
NSLog(#"The results array is %#", results);
Rather than '==' I've tried a mix of 'IN' and '#K' and 'self' but it either crashes or results are 0.
NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [[array2 valueForKey:#"name"] containsObject:[evaluatedObject objectForKey:#"name"]];
}];
This should work with IN:
NSArray *matchSet = [self.array2 valueForKey:#"name"];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"name IN #%",matchSet];
Typed in Safari.
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-215891
Here's a quick example of how you could accomplish this:
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSArray *arrayOne = #[#{#"name": #"Alvin"}, #{#"name": #"Brian"}, #{#"name": #"Charlie"}];
BMPPerson *alvin = [[BMPPerson alloc] initWithName:#"Alvin"];
BMPPerson *charlie = [[BMPPerson alloc] initWithName:#"Charlie"];
NSArray *arrayTwo = #[alvin, charlie];
NSArray *values = [arrayTwo valueForKey:#"name"];
NSMutableArray *filteredValues = [NSMutableArray array];
[arrayOne enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *name = [obj valueForKey:#"name"];
if ([values containsObject:name]) {
[filteredValues addObject:name];
}
}];
NSLog(#"%#", filteredValues);
}
return 0;
}
In the example, arrayOne is an NSArray of NSDictionary objects. Each object has a key of name.
The objects contained in arrayTwo are a basic NSObject subclass that has a name property.
To get the values of the name properties for all of the objects in arrayTwo we make use of the key-value coding method -valueForKey: which calls -valueForKey: on each object in the receiver and returns an array of the results.
We then create an NSMutableArray to hold the filtered results from arrayOne.
Next we enumerate the objects in arrayOne using the -enumerateObjectsUsingBlock: method. In this example, we know that the obj argument is an NSDictionary that has a key of name. Instead of casting to an NSDictionary and calling -objectForKey: we can simply call -valueForKey: and store the value in our local variable name. We then check to see if name is in the values array and if it is, add it to our filteredValues.
I have a NSArray that contains dictionary objects. The structure of array looks like this:
Data = (
{
Date = "07/11/2013";
LotNumber = 1;
PartyName = "Gaurav Wadhwani";
Quantity = 500;
},
{
Date = "07/11/2013";
LotNumber = 2;
PartyName = "Gaurav Wadhwani";
Quantity = 600;
}
)
I am using a Search and Display controller which allows the user to search through LotNumber, PartyName or Date. I know how to use Scope titles and search bar. However, I am unable to use NSPredicate to get correct results. This is my code:
NSString *searchParameter = #"LotNumber";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K contains[cd] %#", searchParameter, searchText];
filteredGoodsArray = [NSMutableArray arrayWithArray:[data filteredArrayUsingPredicate:predicate]];
NSLog(#"Filtered Array = %#", filteredGoodsArray);
I always get blank results in filtered array. Could you tell me what's wrong here?
Thank You.
You can use -predicateWithBlock: to filter your dataArray
- (NSArray *)filterArray:(NSArray *)dataArray WithSearchText:(NSString *)searchText ScopeTitle:(NSString *)scopeTitle {
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
//this is the dictionary in your dataArray
NSDictionary *dictionary = (NSDictionary *)evaluatedObject;
NSString *key = #"";
//get key based on your selected scope
if ([scopeTitle isEqualToString:#"Lot"])
key = #"LotNumber";
else if ([scopeTitle isEqualToString:#"Party"])
key = #"PartyName";
//grab the value from the dictionary with the corresponding key
NSString *value = [dictionary objectForKey:key];
//if the value contains your searchText return YES to add the object to the filtered array
//if not it returns NO to filter it out of the array
return [value rangeOfString:searchText options:NSCaseInsensitiveSearch].location != NSNotFound;
}];
//filter your dataArray using the predicate
return [dataArray filteredArrayUsingPredicate:predicate];
}
I have a word list stored in an NSArray, I want to find all the words in it with the ending 'ing'.
Could someone please provide me with some sample/pseudo code.
Use NSPredicate to filter NSArrays.
NSArray *array = #[#"test", #"testing", #"check", #"checking"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF ENDSWITH 'ing'"];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
Let's say you have an array defined:
NSArray *wordList = // you have the contents defined properly
Then you can enumerate the array using a block
// This array will hold the results.
NSMutableArray *resultArray = [NSMutableArray new];
// Enumerate the wordlist with a block
[wordlist enumerateObjectsUsingBlock:(id obj, NSUInteger idx, BOOL *stop) {
if ([obj hasSuffix:#"ing"]) {
// Add the word to the result list
[result addObject:obj];
}
}];
// resultArray now has the words ending in "ing"
(I am using ARC in this code block)
I am giving an example using blocks because its gives you more options should you need them, and it's a more modern approach to enumerating collections. You could also do this with a concurrent enumeration and get some performance benefits as well.
Just loop through it and check the suffixes like that:
for (NSString *myString in myArray) {
if ([myString hasSuffix:#"ing"]){
// do something with myString which ends with "ing"
}
}
NSMutableArray *results = [[NSMutableArray alloc] init];
// assuming your array of words is called array:
for (int i = 0; i < [array count]; i++)
{
NSString *word = [array objectAtIndex: i];
if ([word hasSuffix: #"ing"])
[results addObject: word];
}
// do some processing
[results release]; // if you're not using ARC yet.
Typed from scratch, should work :)
I have an NSArray of objects with properties such as firstName, lastName, clientID etc. and i would like to perform a search on the array based on a search keyword. This keyword must be checked against the first name and the last name properties and return a subset of the original array that contains only those objects whose first/last name contain the search term. Is there any efficient/fast way to do this?
As a second thought, I think -filteredArrayUsingPredicate: might be better for you.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K = %#", #"firstName", #"Bob"];
NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
This returns a sub-array of objects from the array that have the first name of "Bob".
I think your looking for -indexesOfObjectsPassingTest:
NSIndexSet *indexSet = [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
MyObject *myObject = (MyObject *)obj;
return [myObject.firstName isEqualToString:#"Bob"];
}];
This returns an index set of all the objects in the array with the first name of "Bob".
Another approach returning a new array containing only matching objects:
-(NSArray *)matchingClientsFromArray:(NSArray *)objects withFirstName:(NSString *)firstName andLastName:(NSString *)lastName{
NSMutableArray *objectArray = [NSMutableArray new];
for (Client *client in objectArray){
if ([client.firstName isEqualToString:firstName] &&
[client.lastName isEqualToString:lastName]) {
[objectArray addObject:client];
}
}
return [objectArray copy];
}