简体   繁体   中英

Compare NSDates of two Different NSArrays

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?

Combining two arrays:

NSMutableArray *combinedArr = [[originalArray1 arrayByAddingObjectsFromArray: 
    originalArray2] mutableCopy];

To sort an NSMutableArray :

  • Write a method that will return an 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.
  • With that method written, in hand, and ready to go, sort the array:
 [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.

There are many ways to do what you want. The following is an approach.

  1. Create classes for Tweet and Instagram Picture
  2. 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; } 
  3. Combine both input arrays

     NSMutableArray *combinedArray = [[NSMutableArray alloc] init]; [combinedArray addObjectsFromArray:tweets]; [combinedArray addObjectsFromArray:instagramPictures]; 
  4. Sort the combined array by comparator

     NSArray *sortedCombinedArray = [combinedArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1.createdDate compare:obj2.createdDate]; }]; 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM