I have NSSArray
having Custom Objects, To sort the Custom Object with Custom logic
Custom object having two property:
@property (nonatomic, strong) NSString *objectName;
@property (nonatomic, assign) BOOL isValidName;
if isValidName property is false, Then the custom object should be last sorting order. for the objects isValidName property is true, Then it should be sort with property objectName in ascending.
I can do with for loop
by finding objects having property isValidName false then remove the objects from the array and then sort the array after that I can add the objects which are having property isValidName false. I don't want to do that.
I want that something like below option, But it is not working. Please help in regard
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSArray *sortedTopics = [obj sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
if (obj1.isValidName) {
return NSOrderedAscending;
}
return [obj1.objectName compare: obj2.objectName options:NSCaseInsensitiveSearch];
}];
obj = sortedTopics;
}];
I dont really recreated the stuff you did, but i hope this would work for you: arr should be NSMutableArray
NSSortDescriptor *validSort = [[NSSortDescriptor alloc] initWithKey:@"isValidName" ascending:NO];
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"objectName" ascending:YES];
[arr sortUsingDescriptors:[NSArray validSort, nameSort, nil]];
So if your object.isValidName
= false it will push to after the one have it true and also sort by name
Try using NSPredicate
NSMutableArray *arrFinalSortedArray = [NSMutableArray new];
NSArray *yourObjectArray = @[@{@"isValidName":@"YES" ,@"objectName":@"ABC"},@{@"isValidName":@"NO",@"objectName":@"EFG"},@{@"isValidName":@"YES",@"objectName":@"BCD"},@{@"isValidName":@"YES",@"objectName":@"CDE"},@{@"isValidName":@"NO",@"objectName":@"DEF"}];
// filter for NO flag
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isValidName ==[c] %@", @"NO"];
NSArray *NOContainerArray = [yourObjectArray filteredArrayUsingPredicate:predicate];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"objectName" ascending:YES];
NOContainerArray = [NOContainerArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
// filter for NO flag
predicate = [NSPredicate predicateWithFormat:@"isValidName ==[c] %@", @"YES"];
NSArray *YESContainerArray = [yourObjectArray filteredArrayUsingPredicate:predicate];
descriptor = [NSSortDescriptor sortDescriptorWithKey:@"objectName" ascending:YES];
YESContainerArray = [YESContainerArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]];
// add to all YES and NO array into the final array which is the your result
[arrFinalSortedArray addObjectsFromArray:YESContainerArray];
[arrFinalSortedArray addObjectsFromArray:NOContainerArray];
NSLog(@"%@",arrFinalSortedArray);
I think you almost had it, but you shouldn't be using enumerateObjectsUsingBlock
. Instead use sortedArrayUsingComparator
and assign the result to a new array:
NSArray *sortedTopics = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2){
if (!obj1.isValidName)
return NSOrderedDescending;
return [obj1.objectName compare: obj2.objectName options:NSCaseInsensitiveSearch];
}];
If you have an NSMutableArray
you can call sortUsingComparator:
on it instead and avoid creating a new array.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.