2012-12-28 4 views
1

다음 이름 및 날짜 쌍이있는 NSArray가 있습니다. 참고 : 날짜 내 배열의 이름 날짜 쌍의 수백이있다NSDate 범위를 사용하여 NSArray를 검색하십시오.

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

내 사용자 정의 배열의 인덱스 1에 항상이다. 따라서 주어진 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'배열 중 하나입니까? –

+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의 방법입니다. 그래서 시작, 끝, 날짜는 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

NSArrayNSArray 인 것으로 가정하면 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

나를 도와 주신 모든 분들께 감사드립니다. 다음은 칼 캘린더 프로젝트에서 현재 작동하고있는 코드입니다. 아마도 미래에 관심이있는 사람들에게 도움이되기를 바랍니다. 이 게시물에 답변 한 다른 사람들이 더 일반적인 답변을 가지고 있지만

+0

공유 해 주셔서 감사합니다. for-loop 방식으로 배열을 필터링하는 것이 효과적 일지라도 정말 우아하지는 않습니다. NSArray는 필터를 수행하기 위해 술어 또는 블록 기반의 특정 메소드를 가지고 있습니다. @ Monolo의 답이나 광산을 확인해 보시기 바랍니다. –