2012-12-28 67 views
1

我有一個NSArray,其中包含以下名稱和日期對。注:日期始終在我的自定義陣列的索引1中使用NSDate範圍搜索NSArray

MyCustomArray: 
(
"Toms Bday" 
"2012-01-10" 
) 
(
"Jesscia Bday" 
"2012-01-27" 
) 
(
"Jills Bday" 
"2012-03-03" 
) 
(
"Joes Bday" 
"2012-04-15" 
) 

我的數組中有數百個名稱日期對。因此,對於給定的StartDate =「2012-01-01」和endDate =「2012-01-31」,我只想得到以下記錄。我怎麼做?

(
    "Toms Bday" 
    "2012-01-10" 
    ) 
    (
    "Jesscia Bday" 
    "2012-01-27" 
    ) 

我看着這個帖子Why can't NSDate be compared using <or>?,但仍然無法弄清楚。

+0

所以這是一個數組的數組,其中第一個項目是一個'NSString'代表一個日期,對吧? – 2012-12-28 14:54:08

+0

是的你是正確的 –

回答

3

考慮您的日期,有一個非常簡單的格式,你可以把它們比爲字符串,其結果應該是正確的:

NSString *start = @"2012-01-01"; 
NSString *end = @"2012-01-31"; 

NSString *date = @"2012-01-10"; 

if ([start compare:date] == NSOrderedAscending && 
    [end compare:date] == NSOrderedDescending) { 
    // Note: might be descending for start and ascending for end, i'm not 100% sure, try both 

    // valid date 
} 
+3

campare是NSDate的一種方法,所以start,end和date必須是NSDate格式,謝謝 – junaidsidhu

+0

很好的回答,但@JayD是對的。 – danh

+0

將字符串轉換爲日期還有一些工作要做,而且您不會顯示如何過濾原始數組以生成想要的結果。我會說這是一個相當草率和不完整的答案,甚至沒有編譯。 –

1

如果你可以自己(決定數據結構,即,它們不是外部需求),那麼也許你會考慮將內部數組(記錄的數據集,可以這麼說)轉換成字典。

爲您的記錄使用字典的優勢在於Cocoa框架提供了您需要存儲,過濾和通常掛鉤數據的所有功能。

所以允許我提出一個建立如下:

// For the purposes of this piece of code, a hard coded array of dictionaries: 
NSArray *fullArray = @[ 
    @{@"desc": @"Toms Bday", @"bday": [NSDate dateWithString:@"2012-01-10 00:00:00 +00:00"]}, 
    @{@"desc": @"Jesscia Bday", @"bday": [NSDate dateWithString:@"2012-01-27 00:00:00 +00:00"]} 
// etc... 
]; 


// The interval of NSDates that you want to filter 
NSDate *intervalBeginning = [NSDate dateWithString:@"2012-01-15 00:00:00 +00:00"]; 
NSDate *intervalEnd  = [NSDate dateWithString:@"2012-01-31 23:59:59 +00:00"]; 

// Find the relevant record(s): 
NSArray *filteredArray = [fullArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"bday >= %@ and bday <= %@", intervalBeginning, intervalEnd]]; 

完成!

+0

你也可以過濾一個'NSArray'。無論如何,我同意使用和'NSDictionary'來表示單個條目是一個更好的選擇。 –

+0

謝謝。所有這些解決方案都很好,所以我給每個人一個加價! –

1

假設entriesNSArrayNSArray s的NSString s。

NSDateFormatter * formatter = [NSDateFormatter new]; 
[formatter setDateFormat:@"yyyy-MM-dd"]; 

NSString * start = @"2012-01-01"; 
NSDate * startDate = [formatter dateFromString:start]; 

NSString * end = @"2012-01-31"; 
NSDate * endDate = [formatter dateFromString:end]; 

NSIndexSet * indexes = [entries indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { 
    NSString * dateString = obj[1]; // retrieve the date string 
    NSDate * date = [formatter dateFromString:dateString]; 

    return !([date compare:startDate] == NSOrderedAscending || 
      [date compare:endDate] == NSOrderedDescending); 
}]; 

NSArray * results = [entries objectsAtIndexes:indexes]; 

什麼我在這裏做是過濾通過一個塊定義的通過測試(在開始和結束日期之間)的索引,然後創建與只是這些索引的陣列。

在此之前,您顯然需要使用NSDateFormatter從字符串獲取日期。

我個人喜歡塊比謂詞更好,因爲我認爲它們更易於閱讀。

0

謝謝大家幫助我。以下是我在Kal-Calendar項目中正在使用的代碼。我希望這能幫助任何對未來感興趣的人。雖然其他人回答這個帖子有更好的通用答案

- (void)loadHolidaysFrom:(NSDate *)fromDate to:(NSDate *)toDate delegate:(id<KalDataSourceCallbacks>)delegate 
{ 
    NSLog(@"Fetching B-Days between %@ and %@...", fromDate, toDate); 

    NSDateFormatter *fmt = [[[NSDateFormatter alloc] init] autorelease]; 
    [fmt setDateFormat:@"yyyy-MM-dd"]; 


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 

    NSString *stringsPlistPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"birthdays.plist"]; 

    //READ IN 
    NSMutableArray *arryData = [[NSMutableArray alloc] initWithObjects:nil]; 
    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:stringsPlistPath]; 



    for (id key in dictionary) 
    { 
     [arryData addObject:[dictionary objectForKey:key]]; 
    } 


    for (int i=0; i<[arryData count]; i++) 
    { 

     NSMutableArray *bdayArray = [[NSMutableArray alloc] initWithArray:[arryData objectAtIndex:i]]; 

     NSString *nameStr = [bdayArray objectAtIndex:0]; 
     NSString *bdayStr = [bdayArray objectAtIndex:1]; 

     NSLog(@"nameStr:%@ ... bdayStr:%@ ...", nameStr,bdayStr); 


     NSDate *BirthdayDate = [fmt dateFromString:bdayStr]; 

     if ([fromDate compare:BirthdayDate] == NSOrderedAscending && 
      [toDate compare:BirthdayDate] == NSOrderedDescending) 
     { 
      // valid date 
      //do something interesting here ... and it does! 
     } 

    } 
+0

感謝您的分享。我必須說,使用for-loop方式過濾數組並不真正優雅,即使它有效。 'NSArray'有其特定的方法 - 謂詞或基於塊 - 來執行過濾器。我建議你查看@ Monolo的答案或我的。 –