Mihir Mehta
Mihir Mehta

Reputation: 13833

Can i sort a Array in Swift with custom logic for sorting

I have been through almost all question of stackoverflow regarding it's answer where it says

array.sort({
    $0.name < $1.name
})

But I do not want this at all...

I have Array containing custom objects and I want to sort it as per it's one of the variable name status ... but not is ascending or descending order ... that sorting depends on the status...

Here is the equivalent Objective C code

@interface NSString (StatusComparison)
- (NSComparisonResult)statusCompare:(NSString*)otherStatus;
@end
@implementation NSString (WeekdayComparison)
- (NSComparisonResult)statusCompare:(NSString*)otherDay {

NSArray *allStatus = [NSArray arrayWithObjects:@"Immediate",@"Near",@"Far",@"Unknown",ENTER_IN_REGION,EXIT_REGION,START_MONITORING,FAIL,NOT_STARTED, nil];

    NSUInteger selfIndex = [allStatus indexOfObject:self];
    NSUInteger otherDayIndex = [allStatus indexOfObject:otherDay];

    if (selfIndex < otherDayIndex) {
        return NSOrderedAscending;
    }
    else if (selfIndex > otherDayIndex) {
        return NSOrderedDescending;
    } else {
        return NSOrderedSame;
    }
}
@end

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"status" ascending:YES selector:@selector(statusCompare:)];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
self.dataArray = [self.dataArray sortedArrayUsingDescriptors:sortDescriptors];

How can I do the same thing in Swift. Please read the entire question before marking it as duplicate... It's not duplicate

Upvotes: 1

Views: 863

Answers (3)

vadian
vadian

Reputation: 285072

The Swift equivalent is

dataArray.sortInPlace {
  return allStatus.indexOf($0.status)! < allStatus.indexOf($1.status)!
}

The allStatus array could be declared in the sort closure as well as somewhere in global scope or before the closure in local scope.


In Swift it might be preferable to declare the allStatus contents as enum type with Int raw value type and the status property in your custom class as the enum type. The benefit is a predictable number of cases and no potential optionals.

For example

enum Status : Int {
  case Immediate = 0, Near, Far, Unknown, FAIL
  var stringValue : String  { return String(self) }
}


dataArray.sortInPlace {
  return $0.status.rawValue < $1.status.rawValue
}

You can still get the string representation of the enum cases with

dataArray[0].status.stringValue

Upvotes: 3

sunshinejr
sunshinejr

Reputation: 4854

Simple example in Swift would be:

["Near", "Immediate", "Far"].sort { (status1, status2) in
    let statuses = ["Immediate", "Near", "Far", "Unknown"]
    guard let index1 = statuses.indexOf(status1), index2 = statuses.indexOf(status2) else {
        return false
    }

    return index1 < index2
} // Prints ["Immediate", "Near", "Far"]

Upvotes: 0

Samurai Girl
Samurai Girl

Reputation: 998

array.sort({
    $0.name < $1.name 
})

This is just a short hand for passing closure as an argument. You can have a complete function with two arguments, which you can pass to this sort method.

Have a look at this Swift closures

Upvotes: -1

Related Questions