문제

내가하고 싶은 것은 매우 간단 해 보이지만 웹에서 답을 찾을 수는 없습니다. 나는있다 NSMutableArray 물체의 경우, 그들이 '사람'대상이라고 가정 해 봅시다. 나는 정렬하고 싶다 NSMutableArray 사람에 의해 NSDate.

이 방법과 관련이 있다고 생각합니다.

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(???)];

Java에서는 내 객체를 비교할 수있게 만들거나 Collections.sort를 사용하여 인라인 사용자 정의 비교기와 함께 사용합니다 ... 지구상에서 어떻게 대상 C 에서이 작업을 수행합니까?

도움이 되었습니까?

해결책

방법을 비교하십시오

객체의 비교 방법을 구현하십시오.

- (NSComparisonResult)compare:(Person *)otherObject {
    return [self.birthDate compare:otherObject.birthDate];
}

NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)];

nsSortDescriptor (더 나은)

또는 보통 더 나은 :

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                           ascending:YES];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

배열에 둘 이상을 추가하여 여러 키로 쉽게 정렬 할 수 있습니다. 사용자 정의 비교 방법을 사용하는 것도 가능합니다. 살펴보십시오 문서.

블록 (반짝임!)

Mac OS X 10.6 및 iOS 4 이후 블록으로 분류 할 가능성도 있습니다.

NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
    NSDate *first = [(Person*)a birthDate];
    NSDate *second = [(Person*)b birthDate];
    return [first compare:second];
}];

성능

그만큼 -compare: 그리고 블록 기반 방법은 일반적으로 사용하는 것보다 상당히 빠릅니다. NSSortDescriptor 후자는 KVC에 의존합니다. 의 주요 장점 NSSortDescriptor 메소드는 코드가 아닌 데이터를 사용하여 정렬 순서를 정의하는 방법을 제공한다는 것입니다. 즉, 사용자가 정렬 할 수 있도록 항목을 쉽게 설정할 수 있습니다. NSTableView 헤더 행을 클릭하여

다른 팁

참조 NSMutableArray 방법 sortUsingFunction:context:

a를 설정해야합니다 비교하다 (유형의 두 객체를 취하는 함수 Person, 당신은 두 가지를 비교하기 때문에 Person 물체) 및 a 문맥 매개 변수.

두 개체는 단지 인스턴스입니다 Person. 세 번째 객체는 문자열 (예 : @”birthdate”입니다.

이 함수는 반환됩니다 NSComparisonResult: 돌아옵니다 NSOrderedAscending 만약에 PersonA.birthDate < PersonB.birthDate. 돌아올 것입니다 NSOrderedDescending 만약에 PersonA.birthDate > PersonB.birthDate. 마지막으로 돌아올 것입니다 NSOrderedSame 만약에 PersonA.birthDate == PersonB.birthDate.

이것은 거친 의사 코드입니다. 한 날짜가 "낮은", "더"또는 "동등한"다른 날짜 (예 : Sec

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  if ([firstPerson birthDate] < [secondPerson birthDate])
    return NSOrderedAscending;
  else if ([firstPerson birthDate] > [secondPerson birthDate])
    return NSOrderedDescending;
  else 
    return NSOrderedSame;
}

더 컴팩트 한 것을 원한다면 삼여 사업자를 사용할 수 있습니다.

NSComparisonResult compare(Person *firstPerson, Person *secondPerson, void *context) {
  return ([firstPerson birthDate] < [secondPerson birthDate]) ? NSOrderedAscending : ([firstPerson birthDate] > [secondPerson birthDate]) ? NSOrderedDescending : NSOrderedSame;
}

이 작업을 많이한다면 인라인은 아마도 이것을 약간 상승시킬 수 있습니다.

나는 블록을 사용하여 iOS 4에서 이것을했다. 내 배열의 요소를 ID에서 클래스 유형으로 시전해야했습니다. 이 경우 포인트라는 속성이있는 점수라는 클래스였습니다.

또한 배열의 요소가 올바른 유형이 아닌 경우해야 할 일을 결정해야합니다.이 예를 위해 방금 반환했습니다. NSOrderedSame, 그러나 내 코드에서는 예외입니다.

NSArray *sorted = [_scores sortedArrayUsingComparator:^(id obj1, id obj2){
    if ([obj1 isKindOfClass:[Score class]] && [obj2 isKindOfClass:[Score class]]) {
        Score *s1 = obj1;
        Score *s2 = obj2;

        if (s1.points > s2.points) {
            return (NSComparisonResult)NSOrderedAscending;
        } else if (s1.points < s2.points) {
            return (NSComparisonResult)NSOrderedDescending;
        }
    }

    // TODO: default is the same?
    return (NSComparisonResult)NSOrderedSame;
}];

return sorted;

추신 : 이것은 내림차순으로 정렬됩니다.

iOS 4에서 시작하여 정렬에 블록을 사용할 수도 있습니다.

이 특정 예에서는 배열의 객체에 '위치'메소드가 있다고 가정합니다. NSInteger.

NSArray *arrayToSort = where ever you get the array from... ;
NSComparisonResult (^sortBlock)(id, id) = ^(id obj1, id obj2) 
{
    if ([obj1 position] > [obj2 position]) 
    { 
        return (NSComparisonResult)NSOrderedDescending;
    }
    if ([obj1 position] < [obj2 position]) 
    {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
};
NSArray *sorted = [arrayToSort sortedArrayUsingComparator:sortBlock];

참고 : "정렬 된"배열이 자동으로 표시됩니다.

나는 모든 것을 시도했지만 이것은 나를 위해 효과가있었습니다. 수업에는 "이름이"다른 수업이 있습니다.crimeScene","그리고 "의 재산으로 분류하고 싶어crimeScene".

이것은 매력처럼 작동합니다.

NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"crimeScene.distance" ascending:YES];
[self.arrAnnotations sortUsingDescriptors:[NSArray arrayWithObject:sorter]];

누락 된 단계가 있습니다 Georg Schölly의 두 번째 대답, 그러나 그것은 잘 작동합니다.

NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                              ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptor:sortDescriptors];
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"birthDate" ascending:YES] autorelease];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingDescriptors:sortDescriptors];

고마워요, 잘 작동합니다 ...

당신의 Person 객체는 방법을 구현해야합니다 compare: 다른 사람이 필요합니다 Person 대상과 반환 NSComparisonResult 두 객체 사이의 관계에 따라.

그러면 당신은 전화 할 것입니다 sortedArrayUsingSelector: ~와 함께 @selector(compare:) 그리고 그것은 완료해야합니다.

다른 방법이 있지만, 내가 아는 한 Cocoa-equiv는 Comparable 상호 작용. 사용 sortedArrayUsingSelector: 아마도 가장 고통스러운 방법 일 것입니다.

iOS 4 블록은 당신을 구할 것입니다 :)

featuresArray = [[unsortedFeaturesArray sortedArrayUsingComparator: ^(id a, id b)  
{
    DMSeatFeature *first = ( DMSeatFeature* ) a;
    DMSeatFeature *second = ( DMSeatFeature* ) b;

    if ( first.quality == second.quality )
        return NSOrderedSame;
    else
    {
        if ( eSeatQualityGreen  == m_seatQuality || eSeatQualityYellowGreen == m_seatQuality || eSeatQualityDefault  == m_seatQuality )
        {
            if ( first.quality < second.quality )
                return NSOrderedAscending;
            else
                return NSOrderedDescending;
        }
        else // eSeatQualityRed || eSeatQualityYellow
        {
            if ( first.quality > second.quality )
                return NSOrderedAscending;
            else
                return NSOrderedDescending;
        } 
    }
}] retain];

http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html 약간의 설명

을 위한 NSMutableArray, 사용 sortUsingSelector 방법. 새 인스턴스를 만들지 않고도 정렬합니다.

목적을 위해 다음 일반 방법을 사용할 수 있습니다. 문제를 해결해야합니다.

//Called method
-(NSMutableArray*)sortArrayList:(NSMutableArray*)arrDeviceList filterKeyName:(NSString*)sortKeyName ascending:(BOOL)isAscending{
    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:sortKeyName ascending:isAscending];
    [arrDeviceList sortUsingDescriptors:[NSArray arrayWithObject:sorter]];
    return arrDeviceList;
}

//Calling method
[self sortArrayList:arrSomeList filterKeyName:@"anything like date,name etc" ascending:YES];

배열을 정렬하는 경우 NSNumbers, 당신은 1 개의 전화로 정렬 할 수 있습니다.

[arrayToSort sortUsingSelector: @selector(compare:)];

배열의 개체가 있기 때문에 작동합니다 (NSNumber 객체) 비교 방법을 구현하십시오. 당신은 똑같은 일을 할 수 있습니다 NSString 객체 또는 비교 방법을 구현하는 사용자 정의 데이터 객체 배열의 경우.

다음은 비교기 블록을 사용한 몇 가지 예제 코드입니다. 각 사전에는 "Sort_key"의 숫자가 포함 된 사전 배열을 정렬합니다.

#define SORT_KEY @\"sort_key\"

[anArray sortUsingComparator: 
 ^(id obj1, id obj2) 
  {
  NSInteger value1 = [[obj1 objectForKey: SORT_KEY] intValue];
  NSInteger value2 = [[obj2 objectForKey: SORT_KEY] intValue];
  if (value1 > value2) 
{
  return (NSComparisonResult)NSOrderedDescending;
  }

  if (value1 < value2) 
{
  return (NSComparisonResult)NSOrderedAscending;
  }
    return (NSComparisonResult)NSOrderedSame;
 }];

위의 코드는 각 정렬 키에 대한 정수 값을 얻고이를 수행하는 방법의 그림으로 비교하는 작업을 수행합니다. 부터 NSNumber 객체는 비교 방법을 구현하고 훨씬 더 간단하게 다시 작성할 수 있습니다.

 #define SORT_KEY @\"sort_key\"

[anArray sortUsingComparator: 
^(id obj1, id obj2) 
 {
  NSNumber* key1 = [obj1 objectForKey: SORT_KEY];
  NSNumber* key2 = [obj2 objectForKey: SORT_KEY];
  return [key1 compare: key2];
 }];

또는 비교기의 본문은 1 라인으로 증류 될 수도 있습니다.

  return [[obj1 objectForKey: SORT_KEY] compare: [obj2 objectForKey: SORT_KEY]];

코드를 읽기 쉽고 디버깅하기가 더 쉽기 때문에 간단한 진술과 많은 임시 변수를 선호하는 경향이 있습니다. 컴파일러는 어쨌든 임시 변수를 최적화하므로 올인원 버전에는 이점이 없습니다.

나는 작은 카테고리 방법 라이브러리를 만들었습니다. LINQ에서 Objectivec, 그것은 이런 종류의 것을 더 쉽게 만듭니다. 사용 종류 키 선택기가있는 메소드는 다음을 정렬 할 수 있습니다. birthDate 다음과 같이 :

NSArray* sortedByBirthDate = [input sort:^id(id person) {
    return [person birthDate];
}]

방금 사용자 지정 요구 사항을 기반으로 다중 레벨 정렬을 수행했습니다.

// 값을 정렬합니다

    [arrItem sortUsingComparator:^NSComparisonResult (id a, id b){

    ItemDetail * itemA = (ItemDetail*)a;
    ItemDetail* itemB =(ItemDetail*)b;

    //item price are same
    if (itemA.m_price.m_selling== itemB.m_price.m_selling) {

        NSComparisonResult result=  [itemA.m_itemName compare:itemB.m_itemName];

        //if item names are same, then monogramminginfo has to come before the non monograme item
        if (result==NSOrderedSame) {

            if (itemA.m_monogrammingInfo) {
                return NSOrderedAscending;
            }else{
                return NSOrderedDescending;
            }
        }
        return result;
    }

    //asscending order
    return itemA.m_price.m_selling > itemB.m_price.m_selling;
}];

https://sites.google.com/site/greateindiaclub/mobil-apps/ios/multilevelsortinginiosobjectivec

나는 사용했다 SortusingFunction :: 내 프로젝트 중 일부에서 :

int SortPlays(id a, id b, void* context)
{
    Play* p1 = a;
    Play* p2 = b;
    if (p1.score<p2.score) 
        return NSOrderedDescending;
    else if (p1.score>p2.score) 
        return NSOrderedAscending;
    return NSOrderedSame;
}

...
[validPlays sortUsingFunction:SortPlays context:nil];
-(NSMutableArray*) sortArray:(NSMutableArray *)toBeSorted 
{
  NSArray *sortedArray;
  sortedArray = [toBeSorted sortedArrayUsingComparator:^NSComparisonResult(id a, id b) 
  {
    return [a compare:b];
 }];
 return [sortedArray mutableCopy];
}

nsSortDescriptor를 사용하여 사용자 정의 객체와 NSMutableAreray를 정렬합니다.

 NSSortDescriptor *sortingDescriptor;
 sortingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
                                       ascending:YES];
 NSArray *sortArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];

정렬 NSMutableArray 매우 간단합니다 :

NSMutableArray *arrayToFilter =
     [[NSMutableArray arrayWithObjects:@"Photoshop",
                                       @"Flex",
                                       @"AIR",
                                       @"Flash",
                                       @"Acrobat", nil] autorelease];

NSMutableArray *productsToRemove = [[NSMutableArray array] autorelease];

for (NSString *products in arrayToFilter) {
    if (fliterText &&
        [products rangeOfString:fliterText
                        options:NSLiteralSearch|NSCaseInsensitiveSearch].length == 0)

        [productsToRemove addObject:products];
}
[arrayToFilter removeObjectsInArray:productsToRemove];

nscomparator를 사용하여 정렬하십시오

사용자 정의 객체를 정렬하려면 제공해야합니다. NSComparator, 사용자 정의 객체를 비교하는 데 사용됩니다. 블록은 반환합니다 NSComparisonResult 값 두 객체의 순서를 나타내는 값. 전체 배열을 정렬하기 위해 NSComparator 다음 방식으로 사용됩니다.

NSArray *sortedArray = [employeesArray sortedArrayUsingComparator:^NSComparisonResult(Employee *e1, Employee *e2){
    return [e1.firstname compare:e2.firstname];    
}];

nsSortDescriptor를 사용하여 정렬합니다
예를 들어, 맞춤형 클래스의 인스턴스가 포함 된 배열이 있다고 가정 해 봅시다. 다음 예제는 AGE 키에 의해 배열 내용을 오름차순 순서로 정렬하는 데 사용할 수있는 nsSortDescriptor를 만드는 방법을 보여줍니다.

NSSortDescriptor *ageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
NSArray *sortDescriptors = @[ageDescriptor];
NSArray *sortedArray = [employeesArray sortedArrayUsingDescriptors:sortDescriptors];

사용자 정의 비교를 사용하여 정렬
이름은 문자열이며, 문자열을 정렬하여 사용자에게 제시 할 때 항상 현지화 된 비교를 사용해야합니다. 종종 당신은 또한 사례 둔감 한 비교를 수행하고자합니다. 다음은 (LocalizedStandardCompare :)와 함께 마지막 이름과 이름으로 배열을 주문합니다.

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc]
              initWithKey:@"lastName" ascending:YES selector:@selector(localizedStandardCompare:)];
NSSortDescriptor * firstNameDescriptor = [[NSSortDescriptor alloc]
              initWithKey:@"firstName" ascending:YES selector:@selector(localizedStandardCompare:)];
NSArray *sortDescriptors = @[lastNameDescriptor, firstNameDescriptor];
NSArray *sortedArray = [employeesArray sortedArrayUsingDescriptors:sortDescriptors];

참조 및 자세한 토론은 다음을 참조하십시오.https://developer.apple.com/library/ios/documentation/cocoa/conceptual/sortdescriptors/articles/creating.html
http://www.ios-blog.co.uk/tutorials/objective-c/how-to-sort-nsarray-with-custom-objects/

Swift의 프로토콜 및 기능 프로그래밍은 클래스가 비슷한 프로토콜을 준수하고 프로토콜에 필요한 메소드를 구현 한 다음 정렬 된 (by :)를 사용하여 사용할 필요없이 정렬 된 배열을 작성해야합니다. 그건 그렇고, 변이 가능한 배열.

class Person: Comparable {
    var birthDate: NSDate?
    let name: String

    init(name: String) {
        self.name = name
    }

    static func ==(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate === rhs.birthDate || lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedSame
    }

    static func <(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedAscending
    }

    static func >(lhs: Person, rhs: Person) -> Bool {
        return lhs.birthDate?.compare(rhs.birthDate as! Date) == .orderedDescending
    }

}

let p1 = Person(name: "Sasha")
p1.birthDate = NSDate() 

let p2 = Person(name: "James")
p2.birthDate = NSDate()//he is older by miliseconds

if p1 == p2 {
    print("they are the same") //they are not
}

let persons = [p1, p2]

//sort the array based on who is older
let sortedPersons = persons.sorted(by: {$0 > $1})

//print sasha which is p1
print(persons.first?.name)
//print James which is the "older"
print(sortedPersons.first?.name)

제 경우에는 "SortedArrayusingComparator"를 사용하여 배열을 정렬합니다. 아래 코드를보십시오.

contactArray = [[NSArray arrayWithArray:[contactSet allObjects]] sortedArrayUsingComparator:^NSComparisonResult(ContactListData *obj1, ContactListData *obj2) {
    NSString *obj1Str = [NSString stringWithFormat:@"%@ %@",obj1.contactName,obj1.contactSurname];
    NSString *obj2Str = [NSString stringWithFormat:@"%@ %@",obj2.contactName,obj2.contactSurname];
    return [obj1Str compare:obj2Str];
}];

또한 내 대상은

@interface ContactListData : JsonData
@property(nonatomic,strong) NSString * contactName;
@property(nonatomic,strong) NSString * contactSurname;
@property(nonatomic,strong) NSString * contactPhoneNumber;
@property(nonatomic) BOOL isSelected;
@end

신속하게 배열을 정렬하십시오


을 위한 Swifty 아래 사람은 전 세계적으로 위의 목표를 달성하기위한 매우 깨끗한 기술입니다. 예제의 사용자 정의 클래스를 갖도록합시다 User 일부 속성이 있습니다.

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var createdDate: Date?
}

이제 우리는 createdDate 오름차순 및/또는 내림차순. 따라서 날짜 비교 기능을 추가하겠습니다.

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var createdDate: Date?
    func checkForOrder(_ otherUser: User, _ order: ComparisonResult) -> Bool {
        if let myCreatedDate = self.createdDate, let othersCreatedDate = otherUser.createdDate {
            //This line will compare both date with the order that has been passed.
            return myCreatedDate.compare(othersCreatedDate) == order
        }
        return false
    }
}

이제 가자 extensionArray ~을 위한 User. 간단한 단어로는 배열에 대해서만 몇 가지 방법을 추가 할 수 있습니다. User 그 안에 물체.

extension Array where Element: User {
    //This method only takes an order type. i.e ComparisonResult.orderedAscending
    func sortUserByDate(_ order: ComparisonResult) -> [User] {
        let sortedArray = self.sorted { (user1, user2) -> Bool in
            return user1.checkForOrder(user2, order)
        }
        return sortedArray
    }
}

오름차순 주문을위한 사용

let sortedArray = someArray.sortUserByDate(.orderedAscending)

내림차순 주문을위한 사용

let sortedArray = someArray.sortUserByDate(.orderedAscending)

같은 순서에 대한 사용

let sortedArray = someArray.sortUserByDate(.orderedSame)

위의 방법 extension 인 경우에만 액세스 할 수 있습니다 Array 유형입니다 [User] || Array<User>

SortDescriptor를 만들어야하며 아래와 같이 SortDescriptor를 사용하여 NSMutableARRay를 정렬 할 수 있습니다.

 let sortDescriptor = NSSortDescriptor(key: "birthDate", ascending: true, selector: #selector(NSString.compare(_:)))
 let array = NSMutableArray(array: self.aryExist.sortedArray(using: [sortDescriptor]))
 print(array)

중첩 된 물체에 이와 같이 사용하십시오.

NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastRoute.to.lastname" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSMutableArray *sortedPackages = [[NSMutableArray alloc]initWithArray:[packages sortedArrayUsingDescriptors:@[sortDescriptor]]];

Lastroute는 하나의 객체이며 해당 객체는 TO Object를 유지하며, 객체는 마지막 이름 문자열 값을 유지합니다.

NSSortDescriptor  *sort = [[NSSortDescriptor alloc] initWithKey:@"_strPrice"
                                                 ascending:sortFlag selector:@selector(localizedStandardCompare:)] ;
NSMutableArray *stockHoldingCompanies = [NSMutableArray arrayWithObjects:fortune1stock,fortune2stock,fortune3stock,fortune4stock,fortune5stock,fortune6stock , nil];

NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"companyName" ascending:NO];

[stockHoldingCompanies sortUsingDescriptors:[NSArray arrayWithObject:sortOrder]];

NSEnumerator *enumerator = [stockHoldingCompanies objectEnumerator];

ForeignStockHolding *stockHoldingCompany;

NSLog(@"Fortune 6 companies sorted by Company Name");

    while (stockHoldingCompany = [enumerator nextObject]) {
        NSLog(@"===============================");
        NSLog(@"CompanyName:%@",stockHoldingCompany.companyName);
        NSLog(@"Purchase Share Price:%.2f",stockHoldingCompany.purchaseSharePrice);
        NSLog(@"Current Share Price: %.2f",stockHoldingCompany.currentSharePrice);
        NSLog(@"Number of Shares: %i",stockHoldingCompany.numberOfShares);
        NSLog(@"Cost in Dollars: %.2f",[stockHoldingCompany costInDollars]);
        NSLog(@"Value in Dollars : %.2f",[stockHoldingCompany valueInDollars]);
    }
    NSLog(@"===============================");
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top