Filter NSArray of custom objects - objective-c

I have a NSArray of Contact objects, we can call it contacts. Contact is a superclass, FacebookGroup and Individual are subclasses of Contact. FacebookGroup has a property called individuals which is a set of Individual objects.
I also have a NSArray of NSString objects, we can call it userIDs.
What I want to do is create a new NSArray from the existing contacts array that match the userIDs in userIDs.
So if contacts has 3 Contact objects with userID 1,2 and 3. And my userIDs has a NSString object 3. Then I want the resulting array to contain Contact which equals userID 3.
Contact.h
Contact : NSObject
FacebookGroup.h
FacebookGroup : Contact
#property (nonatomic, strong) NSSet *individuals;
Individual.h
Individual : Contact
#property (nonatomic, strong) NSString *userID;

NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userId = %#", myContact.userId];
NSArray *filteredArray = [contacts filteredArrayUsingPredicate:predicate];

Is this what you are looking for?
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userID IN %#", userIDs];
NSArray *filtered = [contacts filteredArrayUsingPredicate:predicate];

i'm expecting you want like this once see this one,
NSMutableArray *names = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", nil];
NSMutableArray *ids = [NSMutableArray arrayWithObjects:#"1", #"2", #"2", #"3", nil];
NSMutableArray *array=[[NSMutableArray alloc]init];
for(int i=0;i<[ids count];i++){
if([[ids objectAtIndex:i] isEqualToString:#"2"])
[array addObject:[names objectAtIndex:i]];
}
NSLog(#"%#",array);
O/P:-
(
two,
three
)

Related

Merging NSArrays to create new array with objects

I have 3 NSArrays, each one with 6 objects:
NSArray *A [Joe, John, Jay, Jason, Jonah, Jeremiah];
NSArray *B [Doe, Smith, Scott, Jackson, Johnson, Lewis];
NSArray *C [1,2,3,4,5,6];
My model is:
#interface Person : NSObject
#property NSString *firstName;
#property NSString *lastName;
#property NSString *number;
#end
I need to create a forth array where each person object has a firstName, lastName, number.
NSArray *D = [0]Joe, Doe, 1
[1]John, Smith, 2
[2]Jay.Scott,3
[3]Jason, Jackson, 4
[4]Jonah, Johnson, 5
[5]Jeremiah. Lewis, 6
How can I do this?
You can do something like following: (On a side note, please declare your class property with proper attributes)
NSArray *A = #[#"Joe", #"John", #"Jay", #"Jason", #"Jonah", #"Jeremiah"];
NSArray *B = #[#"Doe", #"Smith", #"Scott", #"Jackson", #"Johnson", #"Lewis"];
NSArray *C = #[#1, #2, #3, #4, #5, #6];
NSMutableArray *D = [[NSMutableArray alloc] initWithCapacity:A.count];
for (int i=0; i < A.count; i++)
{
Person *p = [[Person alloc] init];
p.firstName = [A objectAtIndex:i];
p.lastName = [B objectAtIndex:i];
p.number = [C objectAtIndex:i];
[D addObject:d];
}
Let me know, how it goes.
Try using enumerateObjectsUsingBlock for array :-
NSArray *A = #[#"Joe", #"John", #"Jay", #"Jason", #"Jonah", #"Jeremiah"];
NSArray *B = #[#"Doe", #"Smith", #"Scott", #"Jackson", #"Johnson", #"Lewis"];
NSArray *C = #[#1, #2, #3, #4, #5, #6];
NSMutableArray *mutArr=[NSMutableArray array];
[A enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
Person *p=[[Person alloc]init];
p.firstName=A[idx];
p.lastName=B[idx];
p.number=C[idx];
[mutArr addObject:p];
}];
NSLog(#"person=%#",mutArr);

Sorting and matching

NSMutableArray *full_text_list = [[NSMutableArray alloc]init];
[full_text_list addObject:#"for"];
[full_text_list addObject:#"for your information"];
[full_text_list addObject:#"you"];
[full_text_list addObject:#"at"];
NSMutableArray *short_text_list = [[NSMutableArray alloc]init];
[short_text_list addObject:#"4"];
[short_text_list addObject:#"fyi"];
[short_text_list addObject:#"u"];
[short_text_list addObject:#"#"];
i dont want to sort the second array. i want to get the appropriate element based on index.
I want to sort only the full_text_list array based on length, so i tried a below
NSSortDescriptor * descriptors = [[[NSSortDescriptor alloc] initWithKey:#"length"
ascending:NO] autorelease];
NSArray * sortedArray = [full_text_list sortedArrayUsingDescriptors:
[NSArray arrayWithObject:descriptors]];
and the above code works fine.But i am not sure how to match short_text_list array with new sorted array
So when doing like [full_text_list objectatindex:0] and [short_text_list objectatindex:0] will not match
result would be "for your information" and "for" but the result should be "for your information" and "fyi"
Please let me know
How should it match? You have two arrays and are just sorting one and expect the second one automagically gets sorted too? This can not work. Why don't you just build a dictionary with the long information as key and the short one as value or vs?
A second way to do this would be:
// Create your two arrays and then combine them into one dictionary:
NSDictionary *textDict = [NSDictionary dictionaryWithObjects:short_text_list
forKeys:full_text_list];
// Create your sorted array like you did before:
NSSortDescriptor * descriptors = [[[NSSortDescriptor alloc] initWithKey:#"length" ascending:NO] autorelease];
NSArray * sortedArray = [full_text_list sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptors]];
// Then to access short_text, you would use:
NSString *object0ShortText = [textDict objectForKey:[sortedArray objectAtIndex:0]];
I would create a new class which contains both values and insert that into the array instead of creating the two separate array's in the first place:
#interface TextList : NSManagedObject
#property (nonatomic, retain) NSString *full_text;
#property (nonatomic, retain) NSString *short_text;
- (TextList *)initWithFullText:(NSString *)full_text shortText:(NSString *)short_text;
#end
Create your .m file, and then when you want to use it, use something like:
NSMutableArray *full_text_list = [[NSMutableArray alloc]init];
[full_text_list addObject:[TextList initWithFullText:#"for" shortText:#"4"]];
[full_text_list addObject:[TextList initWithFullText:#"for your information" shortText:#"fyi"]];
[full_text_list addObject:[TextList initWithFullText:#"you" shortText:#"u"]];
[full_text_list addObject:[TextList initWithFullText:#"at" shortText:#"#"]];
Then perform the sort:
NSSortDescriptor * descriptors = [[[NSSortDescriptor alloc] initWithKey:#"full_text.length" ascending:NO] autorelease];
NSArray * sortedArray = [full_text_list sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptors]];
Now you can do [[sortedArray objectAtIndex:0] full_text]; and [[sortedArray objectAtIndex:0] short_text]; or
TextList *txtList = [sortedArray objectAtIndex:0];
// txtList.full_text and txtList.short_text are both valid.

Filter an NSArray which contains custom objects

I have UISearchBar, UITableView, a web service which returns a NSMutableArray that contain objects like this:
//Food.h
Food : NSObject {
NSString *foodName;
int idFood;
}
#property (nonatomic, strong) NSString *foodName;
And the array:
Food *food1 = [Food alloc]initWithName:#"samsar" andId:#"1"];
Food *food2 = [Food alloc] initWithName:#"rusaramar" andId:#"2"];
NSSarray *array = [NSArray arrayWithObjects:food1, food2, nil];
How do I filter my array with objects with name beginning with "sa"?
You can filter any array like you'd like to with the following code:
NSMutableArray *array = ...;
[array filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [evaluatedObject.foodName hasPrefix:searchBar.text];
}];
This will filter the array "in-place" and is only accessible on an NSMutableArray. If you'd like to get a new array that's been filtered for you, use the filteredArrayUsingPredicate: NSArray method.
NSString *predString = [NSString stringWithFormat:#"(foodName BEGINSWITH[cd] '%#')", #"sa"];
NSPredicate *pred = [NSPredicate predicateWithFormat:predString];
NSArray *array = [arr filteredArrayUsingPredicate:pred];
NSLog(#"%#", array);

Objective-C : Sorting NSMutableArray containing NSMutableArrays

I'm currently using NSMutableArrays in my developments to store some data taken from an HTTP Servlet.
Everything is fine since now I have to sort what is in my array.
This is what I do :
NSMutableArray *array = [[NSMutableArray arrayWithObjects:nil] retain];
[array addObject:[NSArray arrayWithObjects: "Label 1", 1, nil]];
[array addObject:[NSArray arrayWithObjects: "Label 2", 4, nil]];
[array addObject:[NSArray arrayWithObjects: "Label 3", 2, nil]];
[array addObject:[NSArray arrayWithObjects: "Label 4", 6, nil]];
[array addObject:[NSArray arrayWithObjects: "Label 5", 0, nil]];
First column contain a Label and 2nd one is a score I want the array to be sorted descending.
Is the way I am storing my data a good one ? Is there a better way to do this than using NSMutableArrays in NSMutableArray ?
I'm new to iPhone dev, I've seen some code about sorting but didn't feel good with that.
Thanks in advance for your answers !
This would be much easier if you were to create a custom object (or at least use an NSDictionary) to store the information, instead of using an array.
For example:
//ScoreRecord.h
#interface ScoreRecord : NSObject {
NSString * label;
NSUInteger score;
}
#property (nonatomic, retain) NSString * label;
#property (nonatomic) NSUInteger score;
#end
//ScoreRecord.m
#import "ScoreRecord.h"
#implementation ScoreRecord
#synthesize label, score;
- (void) dealloc {
[label release];
[super dealloc];
}
#end
//elsewhere:
NSMutableArray * scores = [[NSMutableArray alloc] init];
ScoreRecord * first = [[ScoreRecord alloc] init];
[first setLabel:#"Label 1"];
[first setScore:1];
[scores addObject:first];
[first release];
//...etc for the rest of your scores
Once you've populated your scores array, you can now do:
//the "key" is the *name* of the #property as a string. So you can also sort by #"label" if you'd like
NSSortDescriptor * sortByScore = [NSSortDescriptor sortDescriptorWithKey:#"score" ascending:YES];
[scores sortUsingDescriptors:[NSArray arrayWithObject:sortByScore]];
After this, your scores array will be sorted by the score ascending.
You don't need to create a custom class for something so trivial, it's a waste of code. You should use an array of NSDictionary's (dictionary in ObjC = hash in other languages).
Do it like this:
NSMutableArray * array = [NSMutableArray arrayWithObjects:
[NSDictionary dictionaryWithObject:#"1" forKey:#"my_label"],
[NSDictionary dictionaryWithObject:#"2" forKey:#"my_label"],
[NSDictionary dictionaryWithObject:#"3" forKey:#"my_label"],
[NSDictionary dictionaryWithObject:#"4" forKey:#"my_label"],
[NSDictionary dictionaryWithObject:#"5" forKey:#"my_label"],
nil];
NSSortDescriptor * sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:#"my_label" ascending:YES] autorelease];
[array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

Objective-C - How to compare arrays and extract the difference?

Possible duplicate: comparing-two-arrays
I have two NSArray and I'd like to create a new Array with objects from the second array but not
included in the first array.
Example:
NSMutableArray *firstArray = [NSMutableArray arrayWithObjects:#"Bill", #"Ben", #"Chris", #"Melissa", nil];
NSMutableArray *secondArray = [NSMutableArray arrayWithObjects:#"Bill", #"Paul", nil];
The resulting array should be:
[#"Paul", nil];
I solved this problem with a double loop comparing objects into the inner one.
Is there a better solutions ?
[secondArray removeObjectsInArray:firstArray];
This idea was taken from another answer.
If duplicate items are not significant in the arrays, you can use the minusSet: operation of NSMutableSet:
NSMutableArray *firstArray = [NSMutableArray arrayWithObjects:#"Bill", #"Ben", #"Chris", #"Melissa", nil];
NSMutableArray *secondArray = [NSMutableArray arrayWithObjects:#"Bill", #"Paul", nil];
NSSet *firstSet = [NSSet setWithArray:firstArray];
NSMutableSet *secondSet = [NSMutableSet setWithCapacity:[secondArray count]];
[secondSet addObjectsFromArray:secondArray];
[secondSet minusSet:firstSet]; // result is in `secondSet`
I want to compare images from two NSArray.
One Array, I was getting from Core Database. Second I have constant array objects.
I want to know that object of second array is present in Core database or not.
Here is code which i used.
// All object from core data and take into array.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:#"student"];
NSArray *dbresult = [[NSArray alloc]init];
NSError *error;
#try {
dbresult = [context executeFetchRequest:fetchRequest error:&error];
}
#catch (NSException *exception) {
NSString *logerror = [NSString stringWithFormat:#"error in fetching Rooms from coredata = %#",exception.description];
NSLog(logerror)
}
#finally {
}
/*
Get Unused images from list
*/
NSMutableArray *usedImages = [dbresult valueForKey:#"roomImageLocalPath"];
NSMutableSet *fSet = [NSMutableSet setWithArray:usedImages];
NSMutableSet *sSet = [NSMutableSet setWithCapacity:[newImages count]];
[sSet addObjectsFromArray:newImages];
[sSet minusSet:fSet];
NSArray *unusedImages = [secondSet allObjects];
NSLog(#"unusedImages %#",unusedImages);