logo

English

이곳의 프로그래밍관련 정보와 소스는 마음대로 활용하셔도 좋습니다. 다만 쓰시기 전에 통보 정도는 해주시는 것이 예의 일것 같습니다. 질문이나 오류 수정은 siseong@gmail.com 으로 주세요. 감사합니다.

[iOS, MacOS] NSArray 정렬 Sorting에 대해서

by digipine posted Nov 02, 2017
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print

배열을 정리하는 방식은 크게 세 가지로 1)디스크립터를 사용하거나 2)블럭, 3)셀렉터를 사용하는 방법이 있다. 각각이 표현의 차이는 있는데 실제로는 각 요소들을 비교하여 어떤 것이 앞에 오는지를 비교하여 정렬하게 된다.

 

1. sort descriptor를 사용하는 법

 

디스크립터는 NSSortDescriptor의 인스턴스로, 정렬 순서를 표현하는 클래스이다. 코어데이터의 fetch 동작에도 사용되는데, 상당히 간단하고 코코아 바인딩에도 적용할 수 있는 등, 활용 범위가 넓다. 디스크립터를 사용한 정렬은 배열 객체에 sortedArrayUsingDescriptors: 나 sortUsingDescriptors: 메시지를 보내서 적용할 수 있다.

 

이 과정은 다음과 같이 구현한다.

 

NSSortDescriptor 객체를 만든다. 이 객체를 만들 때는 비교의 대상이 되는 키이름과 정렬순서(오름차순인지 내림차순인지) 및 비교에 사용할 메소드를 지정한다.

만약 두 가지 이상의 기준을 사용한다면 디스크립터를 필요한 만큼 만든다.

디스크립터들을 하나의 배열 객체로 만든다.

정렬할 배열 객체에 sortedArrayUsingDescriptors: 메시지를 보내어 정렬된 배열 사본을 얻을 수 있다.

예를 들어 firstName, lastName의 두 개 키로 구성된 사전에 사람의 이름을 넣고, 이 사전들로 구성된 배열을 정렬하는 케이스를 살펴보겠다.

 

NSString *LAST = @"lastName";

NSString *FIRST = @"firstName";

NSMutableArray *array = [NSMutableArray array];

NSArray *sortedArray;

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:

                        @"Jo",FIRST,@"Smith",LAST,nil];

[array addObject:dict];

/**....**/

//위 과정을 반복하여 충분한 수의 사람 이름을 배열에 추가함

 

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc]

                                          initWithKey:LAST

                                           ascending:YES

                                            selector:@selector(localizedCaseInsensitiveCompare:)];

NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc]

                          initWithKey:FIRST

                            ascending:YES

                             selector:@selector(localizedCaseInsensitiveCompare:)];

NSArray *descriptors = [NSArray arrayWithObjects:lastDescriptor, firstDescriptor, nil];

sortedArray = [array sortedArrayUsingDescriptors:descriptors];

 

 

여기서 디스크립터 배열의 원소의 순서는 비교의 우선순위가 된다. 즉 lastname으로 정렬하고, 같은 lastname인 경우에는 firstname으로 다시 정렬하게 된다. 문자열을 비교하고 있으므로 디스크립터를 만들때 localizedCaseInsensitiveCompare: 메소드를 사용했다.

 

2. 블럭코딩으로 정렬하기

 

요건은 간단하다. 디스크립터의 compare: 메소드를 블럭으로 구현하는 것이다. 두 개의 값을 비교해서 뒤에 오는 값이 크거나 뒤의 것이라면 NSOrderedDescending을, 반대라면 NSOrderAscending을, 같다면 NSOrderSame을 내놓으면 된다. 이 원리를 사용하면 블럭으로 소팅하는 것으로 두 개 숫자값 (배열에 들어있으므로 NSNumber가 되어있을)을 비교할 수 있다.

 

NSArray *sortedArray = [array sortedArrayUsingComparator:^(id obj1, id obj2) {

      if ([obj1 integerValue] > [obj2 integerValue])

          return (NSComparisonResult)NSOrderDescending;

      else if ([obj1 integerValue] < [obj2 integerValue] )

          return (NSComparisonResult)NSOrderAscending;

      else

           return (NSComparisonResult)NSOrderSame;

 

}];

 

3. Sort Descriptor 추가 내용

 

정렬 디스크립터는 정렬기준을 표현하는 클래스라고 했다. 처음 예제 코드에서는 셀렉터를 사용하도록 했는데, 만일 해당 키가 문자열이 아니라면 셀렉터를 사용하지 않아도 된다. 만약 NSNumber로 된 키를 사용한다고 하면 다음과 같이 사용하면 된다.

 

NSSortDescriptor *ageDescriptor = [[NSSortDescriptor alloc]

                    initWithKey:@"age" ascending:YES];

NSArray *sortDescriptors = [NSArray arrayWithObject:ageDescriptor];

sortedArray = [studentsArray sortedArrayUsingDescriptors:sortDescriptors];

 

위 예제는 정렬 디스크립터를 만들면서 별도로 비교방법을 주지 않았다. 이 경우에는 디폴트 비교 메소드인 compare:가 사용된다. 이 메소드는 NSNumber와 NSDate 등에 쓰인다. 만약 문자열을 비교한다면 NSString이 가지고 있는 비교 메소드를 사용해야 한다. 문자열이 사용자에게 보여진다면 비교시에는 localizedCompare: / localizedCaseInsensitiveCompare:를 사용해야 한다.

 

 

비교를 위한 메소드는 위의 블럭을 사용한 예에서 살펴보았듯이, 특정 객체에게 메시지를 보내서, 인자로 넘긴 객체와의 순서가 앞이냐, 뒤냐를 판별하게 하는 것이다. 만약 임의의 객체를 정렬해야 한다면 해당 객체에 비교를 위한 메소드를 구현해두거나, 카테고리를 사용하여 추가해서 사용하는 방법을 쓸 수도 있을 것이다.

 
TAG •

List of Articles
No. Subject Author Date Views
36 OSX - Screen Serial Terminal - OSX에서 시리얼 터미널 사용하기 digipine 2017.11.03 7277
35 OSX 사파리 최신 버전 폰트 변경하기 file digipine 2017.11.03 1365
34 [Swift 3] TCPIP Socket 통신 클래스 소스 코드 및 사용법 digipine 2017.11.02 5035
33 [Swift 3] HTTP Request 사용하기, 클래스 소스코드 및 사용법 digipine 2017.11.02 10203
32 [macOS] Sandbox 정책 극복기 Accessing Security Scoped Resource 1 file digipine 2017.11.02 2185
31 [Objective C] NSString 앞뒤 공백 문자 및 줄바꿈 문자 제거 digipine 2017.11.02 1871
30 XCode 8 업데이트 후 Code Sign Error 발생 시 해결법 1 digipine 2017.11.02 920
29 [iOS, MacOS] NSNotification, NSNotificationCenter 사용법 digipine 2017.11.02 1174
28 [iOS, MacOS] Singleton 싱글톤 패턴 사용하기 2 digipine 2017.11.02 1279
» [iOS, MacOS] NSArray 정렬 Sorting에 대해서 digipine 2017.11.02 1041
26 [iOS, MacOS] ATS 보안 정책 가이드 digipine 2017.11.02 839
25 OpenAL PDF, Sample Source file digipine 2017.11.02 986
24 Apple AppStore App Review 시 Reject 피하기 위한 방법 digipine 2017.11.02 629
23 iOS - UILabel 에서 AttributeString 사용하기 digipine 2017.11.02 887
22 iOS - BLE 장치용 ANCS Library for ANCS digipine 2017.11.02 1119
21 iOS - UITextField의 Placeholder Color 색 변경하기 file digipine 2017.11.02 1380
20 iOS - sizeWithFont 메소드 deprecated와 sizeWithAttributes digipine 2017.11.02 902
19 iOS - Sleep Mode Blocking 방법, 앱실행시 슬립모드 진입 방지 digipine 2017.11.01 906
18 iOS , MacOS, iPhone용 GZipStream class 구현하기 digipine 2017.11.01 690
17 iOS - View 이동 전환 하기 총정리 digipine 2017.11.01 820
Board Pagination Prev 1 2 3 Next
/ 3