날짜 문자열 또는 개체의 NSArray 정렬


86

다음 과 같이 NSArray날짜 문자열 (예 : NSString) 이 포함 된 파일이 있습니다. "Thu, 21 May 09 19:10:09 -0700"

NSArray날짜별로 정렬해야 합니다. NSDate먼저 날짜 문자열을 객체 로 변환하는 것에 대해 생각 했지만 NSDate객체 별로 정렬하는 방법에 대해 고민했습니다 .

감사.


이것은 iPhone에만 국한되지 않고 Foundation 프레임 워크와 관련되어 있으므로 다시 태그가 지정되었습니다.
Quinn Taylor

답변:


110

날짜를 NSDateNS (Mutable) Array에 객체 로 저장 한 다음 -[NSArray sortedArrayUsingSelector:또는 사용 하고 매개 변수로 -[NSMutableArray sortUsingSelector:]전달 @selector(compare:)합니다. 이 -[NSDate compare:]방법은 날짜를 오름차순으로 정렬합니다. 이것은를 만드는 NSSortDescriptor것보다 간단하고 자신 만의 비교 함수를 작성하는 것보다 훨씬 간단합니다. ( NSDate객체는 사용자 정의 코드로 달성하고자하는만큼 효율적으로 서로 자신을 비교하는 방법을 알고 있습니다.)


11
원래 질문이 날짜 배열 정렬 또는 날짜 필드가있는 개체 배열 정렬에 대해 묻는 것인지 확실하지 않습니다. 전자 인 경우 가장 쉬운 방법이지만 후자 인 경우 NSSortDescriptor를 사용하는 것이 좋습니다.
smorgan

@smorgan NSSortDescriptor는 nil 날짜를 어떻게 처리합니까?
Ash

도움을 주셔서 감사합니다. Apple Docs에서 더 많이 읽어야한다고 생각하지만 사용하기 전까지는 너무 지루해 보입니다.
Abo3atef

1
스 니펫 코드에서이를 예로 보여줄 수 있습니까? 미리 감사드립니다.
uplearnedu.com

115

내가있는 경우 NSMutableArray"beginDate"유형의 필드 개체가있는 NSDate경우 다음 NSSortDescriptor과 같이 사용하고 있습니다.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

3
나는 많은 시간이 지났음을 알고 있지만 (이전 답변이 수락되었을 때 아직 NSSortDescriptor가 없을 수 있음), 향후 사용을 위해 이것이 올바른 대답이어야합니다.
Vive

1
이것은 멋진 솔루션입니다. code.Thanx 톤의 @vinzenzweber의 몇 줄에 내 문제를 해결
Pratyusha Terli

1
정말 ... 나는 이것이 첫 번째 실행에서 실제로 작동했다는 사실에 충격을 받았습니다! initWithKey는 키가 정의 된 사전을 위해 예약되어 있다고 생각했지만 객체 배열의 속성을 참조하기 만하면됩니다. 빛이 vinzenzweberskavitchski를 비추 게하십시오 !!
whyoz

NSSortDescriptor는 2003 년 말 OS X 10.3 이후로 사용되었습니다. 이것은 날짜가 다른 개체의 필드 인 약간 다른 시나리오입니다. 더욱 현대적인 API를 사용하면 -[NSMutableArray sortUsingComparator:](10.6 이상)을 사용 -compare:하고 두 필드 를 호출 한 결과를 반환하는 블록을 전달할 수 있습니다. 아마도 -valueForKey:각 객체를 호출 하는 것보다 빠를 것 입니다. -sortWithOptions:usingComparator:옵션을 사용 하고 전달하여 동시에 정렬 할 수도 있습니다 .
Quinn Taylor

위의 NSSortDescriptor는 어떻게 nil 날짜를 처리합니까? 만약 그렇다면 어떻게해야하는지 모 독자에게 말해야합니까?
Ash

17

다음과 같은 것을 사용할 수도 있습니다.

//Sort the array of items by  date
    [self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
        return [obj2.date compare:obj1.date];
    }];

그러나 이것은 날짜가 NSDate오히려 a 로 저장되어 있다고 가정합니다NString . 가급적이면 데이터를 원시 형식으로 저장하는 것이 좋습니다. 이와 같은 상황에서 더 쉽게 조작 할 수 있습니다.


9

블록을 사용하여 제자리에서 정렬 할 수 있습니다.

sortedDatesArray = [[unsortedDatesArray sortedArrayUsingComparator: ^(id a, id b) {
    NSDate *d1 = [NSDate dateWithString: s1];
    NSDate *d2 = [NSDate dateWithString: s2];
    return [d1 compare: d2];
}];

날짜 항목보다 더 많이 변환하지 않도록 정렬하기 전에 모든 문자열을 날짜로 변환하는 것이 좋습니다. 모든 정렬 알고리즘은 배열의 항목 수보다 더 많은 문자열을 날짜로 변환합니다 (때로는 훨씬 더 많음).

블록 정렬에 대해 좀 더 알아보기 : http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html


이것은 @notoop에서 제시 한 것과 동일한 차선책 아이디어의 변형입니다. 어쨌든 NSDate로 먼저 변환하는 것이 확실히 갈 길입니다.
퀸 테일러

그는 기본적으로 그냥 더블 포스트 그 당신이 저를 요구하는 경우에 ....에 ..... notoop의 답변을 @로 상당히 불필요한을 내 대답을 넣어
TheCodingArt

이것은 날짜 문자열을 NSDate의 배열로 구문 분석 한 다음 NSDate의 배열을 정렬하는 것보다 훨씬 느립니다. 문자열의 추가 구문 분석이 2 * (n-1) 배가되기 때문입니다. 문자열 구문 분석은 일반적으로 CPU에서 무거운 작업입니다.
CarlLee 2014 년

5

제 경우에 효과가 있었던 것은 다음과 같습니다.

    NSArray * aUnsorted = [dataToDb allKeys];
    NSArray * arrKeys = [aUnsorted sortedArrayUsingComparator : ^ NSComparisonResult (id obj1, id obj2) {
        NSDateFormatter * df = [[NSDateFormatter 할당] init];
        [df setDateFormat : @ "dd-MM-yyyy"];
        NSDate * d1 = [df dateFromString : (NSString *) obj1];
        NSDate * d2 = [df dateFromString : (NSString *) obj2];
        return [d1 비교 : d2];
    }];

dd-MM-yyyy 형식의 모든 키가있는 사전이 있습니다. 그리고 allKeys는 정렬되지 않은 사전 키를 반환하며, 데이터를 시간순으로 표시하고 싶었습니다.


5

당신이 사용할 수있는 sortedArrayUsingFunction:context: . 다음은 샘플입니다.

NSComparisonResult dateSort(NSString *s1, NSString *s2, void *context) {
    NSDate *d1 = [NSDate dateWithString:s1];
    NSDate *d2 = [NSDate dateWithString:s2];
    return [d1 compare:d2];
}

NSArray *sorted = [unsorted sortedArrayUsingFunction:dateSort context:nil];

를 사용하는 NSMutableArray경우 sortArrayUsingFunction:context:대신 사용할 수 있습니다 .


9
이것은 나쁜 생각입니다. 비교 함수는 빠르며 각 비교를 위해 문자열에서 NSDate 객체를 만들 필요가 없어야합니다. 이미-[NSDate compare :]를 사용하고 있다면, 배열에 날짜를 저장하고 -sortedArrayUsingSelector :를 직접 사용하세요.
Quinn Taylor

이미 NSDate 필드가있는 개체를 정렬하는 경우 이것이 좋은 솔루션이라고 생각합니다. 아니?
GnarlyDog

1
배열에 이미 NSDate객체 가 포함되어있는 경우 위의 답변을 사용하거나 -[NSMutableArray sortUsingComparator:]10.6에서 추가 된를 사용할 수도 있습니다 .
Quinn Taylor

다른 키-값 개체와 함께 날짜에 대한 키-값 개체가 NSString으로있는 사전 배열을 사용하는 경우이 솔루션이 지금까지 가장 좋습니다. dateSort 함수 내에서 약간의 수정이 필요합니다. 엄지 척! :)
Erfan

4

가 있으면 with 를 만든 다음을 사용 하여 정렬 NSDate할 수 있습니다 .NSSortDescriptorinitWithKey:ascending:sortedArrayUsingDescriptors:


이 방법은 작동하지만 -sortedArrayUsingSelector : 사용은 조금 더 간단하고 추가 개체를 만들 필요가 없습니다.
Quinn Taylor

사전 편집에서 질문은 " '날짜'키"를 언급 했으므로 이것이 실제로 원시 날짜의 배열이 아니라 하나의 필드로 날짜를 갖는 객체 / 사전의 배열이라고 가정했습니다. 이 경우 sortedArrayUsingSelector : 조회를 수행하려면 사용자 지정 정렬 루틴을 작성해야하므로 좀 더 복잡합니다.
smorgan

네, 혼란스러워서 죄송합니다. 그가 '날짜'키로 자신의 배열을 저장하고 있다고 말하고 있었기 때문에 참조를 정리했으며 질문을 더 혼란스럽게 만들었 음을 깨달았습니다. 더 복잡한 데이터 구조를 고려할 때 상대적 복잡성에 대해 확실히 정확합니다.
Quinn Taylor

2

스위프트 3.0

myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })

1

이것을 변경

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];

키만 변경하세요. Date항상

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.