Reputation: 469
I have two NSArrays
and both of them have different keys for their JSON created at value. The first array is a list of Twitter tweets and the NSDate
key for each object is the created_at
value. The other NSArray
I have is a list of Instagram Pictures and the NSDate
value for the object is created_time
. How would I put both of these arrays into another NSArray
and sort every value based on the time of the object? How would I put both the arrays into an NSDictionary
of the same specifications stated before?
Upvotes: 0
Views: 165
Reputation: 62062
Combining two arrays:
NSMutableArray *combinedArr = [[originalArray1 arrayByAddingObjectsFromArray:
originalArray2] mutableCopy];
To sort an NSMutableArray
:
NSComparisonResult
to describe how the objects you're sorting should be sorted. If you're using something like NSDate
, there's probably already a method written that'll do this for you.[arrToBeSorted sortUsingSelector:@selector(yourSortMethod:)];
An example on putting together the sorting method:
First, you need to return NSComparisonResult
. And the argument you need to accept should be an object of the same class for which you're calling the method on (we're comparing Object A with Object B, both of same class. And finally, you'll put logic in the method to determine what NSComparisonResult
to return.
-(NSComparisonResult)compareObjects:(MyObjectClass*)objectB {
// pseudo code:
if(self comes before objectB) {
return NSOrderedAscending;
} else if(self comes after objectB) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
NSOrderedAscending
says when I do [objectA compareObjects: objectB];
, that A comes before B with this logic. So a sort using [arrToBeSorted sortUsingSelector:@selector(compareObjects:)];
would return the array with objectA
in an index smaller than objectB
.
NSOrderedDescending
would do just the opposite.
NSOrderedSame
says that for this comparison, these two objects are equivalent, so it doesn't matter whether the order is objectA
,objectB
, or objectB
,objectA
, so when compared, the two objects will never trade places. If they're put in an array with objectC
or objectD
, then A and B will sorted around into the right order relative to C and D, but A and B won't be swapped with each other because NSOrderedSame
says that their order, relative to each other, does not matter.
And that's all you're doing with an NSComparisonResult
. You're returning a value that tells the caller how these two objects should be sorted relative to each other. The NSMutableArray
method sortUsingSelector:
using the given selector and iterates through all the objects to get them all in the right order, so for EVERY object in the array, everything before it would return NSOrderedDescending
or NSOrderedSame
for the given selector
the array was sorted with, and everything after it would return NSOrderedAscending
or NSOrderedSame
.
* As a note, for this to work appropriately, everything in the array needs to respond to the sorting selector with the same logic. If you write a method orderByDate
that sorts by some object.date
property, that's fine, as long as every object in the array has the orderByDate
method (and the same logic in it), the .date
property, and they'll all respond in a logical way. If you throw an NSString
in there, you'll have problems (run time exception). If [objectA compareObjects:objectB]
returns NSOrderedAscending
, then [objectB compareObjects: objectA];
must return NSOrderedDescending
.
For putting them into a dictionary, you're going to have to be more clear on the intended structure of the dictionary.
Upvotes: 2
Reputation: 2186
As nhgrif said Combine two arrays by:
NSMutableArray *combinedArr = [[originalArray1 arrayByAddingObjectsFromArray:
originalArray2] mutableCopy];
And for sorting array
-(NSMutableArray *)sortArrayBasedOndate:(NSMutableArray *)combinedArr
{
NSDateFormatter *fmtDate = [[NSDateFormatter alloc] init];
[fmtDate setDateFormat:@"yyyy-MM-dd"];
NSDateFormatter *fmtTime = [[NSDateFormatter alloc] init];
[fmtTime setDateFormat:@"HH:mm"];
NSComparator compareDates = ^(id string1, id string2)
{
NSDate *date1 = [fmtDate dateFromString:string1];
NSDate *date2 = [fmtDate dateFromString:string2];
return [date1 compare:date2];
};
NSComparator compareTimes = ^(id string1, id string2)
{
NSDate *time1 = [fmtTime dateFromString:string1];
NSDate *time2 = [fmtTime dateFromString:string2];
return [time1 compare:time2];
};
NSSortDescriptor * sortDesc1 = [[NSSortDescriptor alloc] initWithKey:@"start_date" ascending:YES comparator:compareDates];
NSSortDescriptor * sortDesc2 = [NSSortDescriptor sortDescriptorWithKey:@"starts" ascending:YES comparator:compareTimes];
[combinedArr sortUsingDescriptors:@[sortDesc1, sortDesc2]];
return combinedArr;
}
Try this.
Upvotes: 1
Reputation: 227
There are many ways to do what you want. The following is an approach.
Write an adapter method to return the item's created date
Class: Tweet
- (NSDate *)createdDate {
return self.created_at;
}
Class: InstagramPicture
- (NSDate *)createdDate {
return self.created_time;
}
Combine both input arrays
NSMutableArray *combinedArray = [[NSMutableArray alloc] init];
[combinedArray addObjectsFromArray:tweets];
[combinedArray addObjectsFromArray:instagramPictures];
Sort the combined array by comparator
NSArray *sortedCombinedArray = [combinedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1.createdDate compare:obj2.createdDate];
}];
Upvotes: 1