ios - nsmutablearray排序 - sortusingcomparator




我如何排序一個NSMutableArray中的自定義對象? (17)

我想要做的事似乎很簡單,但我在網上找不到任何答案。 我有一個對象的NSMutableArray ,並且讓我們說他們是'Person'對象。 我想排序NSMutableArray Person.birthDate是一個NSDate

我認為這與這種方法有關:

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

在Java中,我會讓我的對象實現為Comparable,或者使用Collections.sort和內聯自定義比較器......你怎麼在Objective-C中做到這一點?


在Swift中排序數組

對於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
    }
}

現在讓我們有一個Array for Userextension 。 簡而言之,讓我們只為那些只有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)

只有當Array[User] ||類型時,上述extension方法才可用 Array<User>


比較方法

要么為你的對象實現一個比較方法:

- (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進行排序。


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一些描述


GeorgSchölly的第二個答案有一個缺失的步驟,但當時它工作正常。

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

你必須創建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)

在我的情況下,我使用“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

對於NSMutableArray ,請使用sortUsingSelector方法。 它對它進行排序,而不創建新的實例。


從iOS 4開始,您還可以使用塊進行排序。

對於這個特定的例子,我假設數組中的對像有一個'position'方法,它返回一個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];

注意:“排序”數組將被自動釋放。


您可以使用快速排序對自定義對像數組進行排序。 請使用Swift 4查找下面的示例

func sortArrayOfPersonInAscendingOrder() {
        if self.arrSortingPersons != nil, self.arrSortingPersons.count > 0 {
            self.arrSortingPersons.sort(by: { (person1, person2) -> Bool in
                return person1.birthDate < person2.birthDate
            })
        }

        print("Sorted Array In Ascending Order:\n\(self.arrSortingPersons)")
    }

您的Person對象需要實現一個方法,比如compare:它接受另一個Person對象,並根據這兩個對象之間的關係返回NSComparisonResult

然後你會調用sortedArrayUsingSelector: with @selector(compare:) ,它應該完成。

還有其他方法,但據我所知, Comparable界面沒有Cocoa-equiv。 使用sortedArrayUsingSelector:可能是最簡單的方法。


我只是根據自定義要求完成多級分類。

//對值進行排序

    [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


我嘗試了所有,但這對我有用。 在一個班級中,我有另一個類名為“ crimeScene ”,並且想要通過“ crimeScene ”的屬性進行排序。

這就像一種魅力:

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

我在我的一些項目中使用了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非常簡單:

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];

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

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(@"===============================");

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

謝謝,它工作正常...





nsmutablearray