How do I sort an NSMutableArray with custom objects in it?
Compare method
Either you implement a compare-method for your object:
- (NSComparisonResult)compare:(Person *)otherObject {
return [self.birthDate compare:otherObject.birthDate];
}
NSArray *sortedArray = [drinkDetails sortedArrayUsingSelector:@selector(compare:)];
NSSortDescriptor (better)
or usually even better:
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"birthDate"
ascending:YES];
NSArray *sortedArray = [drinkDetails sortedArrayUsingDescriptors:@[sortDescriptor]];
You can easily sort by multiple keys by adding more than one to the array. Using custom comparator-methods is possible as well. Have a look at the documentation.
Blocks (shiny!)
There's also the possibility of sorting with a block since Mac OS X 10.6 and iOS 4:
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(Person *a, Person *b) {
return [a.birthDate compare:b.birthDate];
}];
Performance
The -compare:
and block-based methods will be quite a bit faster, in general, than using NSSortDescriptor
as the latter relies on KVC. The primary advantage of the NSSortDescriptor
method is that it provides a way to define your sort order using data, rather than code, which makes it easy to e.g. set things up so users can sort an NSTableView
by clicking on the header row.
Sort NSMutableArray with custom objects
You can use sortUsingComparator:
[array sortUsingComparator:^(id obj1, id obj2) {
NSArray *arr1 = obj1;
NSArray *arr2 = obj2;
return [arr1[2] compare:arr2[2]];
}];
Or even (thanks to rmaddy's suggestion):
[array sortUsingComparator:^(NSArray *arr1, NSArray *arr2) {
return [arr1[2] compare:arr2[2]];
}];
If you have a immutable array, you can use sortedArrayUsingComparator:
Sort an NSMutableArray of custom objects Alphabetically
There are several ways to sort a mutable array in objective c.
The simplest I have found is using the [NSMutableArray sortUsingFunction:] method.
For your example, something like this should suffice for the sort function
NSComparisonResult sortTagByName(Tag *tag1, Tag *tag2, void *ignore)
{
return [tag1.name compare:tag2.name];
}
here is a full source listing, that you can use to base your solution on:
#import <Foundation/Foundation.h>
@interface Tag : NSObject {
}
@property (strong, nonatomic) NSString *tid;
@property (strong, nonatomic) NSString *name;
@end
@implementation Tag
@synthesize tid;
@synthesize name;
@end
NSComparisonResult sortTagByName(Tag *tag1, Tag *tag2, void *ignore)
{
return [tag1.name compare:tag2.name];
}
@interface stackExDemo : NSObject
@end
@implementation stackExDemo
+(void) demo {
NSMutableArray * array = [NSMutableArray array];
// add your objects here
[array sortUsingFunction:sortTagByName context:nil];
}
@end
Breaking this down into it's relevant components:
The function
NSComparisonResult sortTagByName(Tag *tag1, Tag *tag2, void *ignore)
{
return [tag1.name compare:tag2.name];
}
This is simply a plain C function (i.e. not a method, so you don't need to define it inside an implementation section of any particular class, however it usually makes sense to define it in the class it applies to).
In the example above, I have defined it after the @end for Tag, simply to make it clear that it it is not a class method.
The parameter I have named "ignore" is the "context" for the sort. In this case there is no context, so we are going to ignore it's value.
Since you are sorting based on an NSString property, NSString's compare method is convenient, however you can also manually return one of {NSOrderedAscending, NSOrderedSame, NSOrderedDescending}
Invoking the sort
[array sortUsingFunction:sortTagByName context:nil];
This repeatedly calls your function for each element in the array, to sort the array.
If you want to be more specific about the type of sort, there are a number of other methods in NSString that can do the comparison, here is a "cut and paste" from NSString.h which should get you started if you want to research it further.
- (NSComparisonResult)compare:(NSString *)string;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange;
- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask range:(NSRange)compareRange locale:(id)locale; // locale arg used to be a dictionary pre-Leopard. We now accepts NSLocale. Assumes the current locale if non-nil and non-NSLocale.
- (NSComparisonResult)caseInsensitiveCompare:(NSString *)string;
- (NSComparisonResult)localizedCompare:(NSString *)string;
- (NSComparisonResult)localizedCaseInsensitiveCompare:(NSString *)string;
In answer to your second question, you would need to do this whenever you have added or moved an element that might cause the array to be unsorted.
Swift - Sorting NSMutableArray with objects in it
You have to use sort
function with a block:
struct Fruit {
var title: String
var desc: String
}
var fruits = [Fruit]()
fruits.append(Fruit(title: "a", desc: "b"))
fruits.append(Fruit(title: "c", desc: "d"))
let sorted = fruits.sort() { $0.title > $1.title }
sorted
NSArray of Objects sorting with Custom Logic
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
Sort NSMutableArray with custom objects by another NSMutableArray
guideArray = < YOUR SECOND ARRAY WITH STRING OBJECT >;
unsortedArray = < YOUR FIRST ARRAY WITH CUSTOM OBJECT >;
[unsortedArray sortUsingComparator:^(id o1, id o2) {
Items *item1 = o1;
Items *item2 = o2;
NSInteger idx1 = [guideArray indexOfObject:item1.ItemID];
NSInteger idx2 = [guideArray indexOfObject:item2.ItemID];
return idx1 - idx2;
}];
NSLog(@"%@",unsortedArray);
iOS how to sort NSMutableArray of custom object contained NSarray of NSNumber?
You can use sortedArrayUsingComparator
for that.
NSArray *sortArray = [array sortedArrayUsingComparator:^NSComparisonResult(StudentScoreObj *obj1,StudentScoreObj *obj2) {
NSNumber *obj1Score = @0, *obj2Score = @0;
if([[obj1 missions] firstObject]) {
obj1Score = @([[[obj1 missions] firstObject] intValue]);
}
if([[obj2 missions] firstObject]) {
obj2Score = @([[[obj2 missions] firstObject] intValue]);
}
return [obj1Score compare:obj2Score];
}];
Sort NSArray of custom objects based on sorting of another NSArray of strings
Hereby, I compare directly the index of obj1.assetID in stringOrder with the index of obj2.assetID in stringOrder (using Objective-C literals for @() to transform NSString => NSNumber)
[items sortUsingComparator:^NSComparisonResult(Attribute *obj1, Attribute *obj2) {
return [@([stringOrder indexOfObject:obj1.assetID]) compare:@([stringOrder indexOfObject:obj2.assetID])]
}];
Or without ObjC literals :
[items sortUsingComparator:^NSComparisonResult(Attribute *obj1, Attribute *obj2) {
return [[NSNumber numberWithInt:[stringOrder indexOfObject:obj1.assetID]] compare:[NSNumber numberWithInt:[stringOrder indexOfObject:obj2.assetID]]]
}];
Related Topics
Detect Tap on a Button in Uitableviewcell for Uitableview Containing Multiple Sections
How to Develop For Iphone Using a Windows Development Machine
How to Export Uiimage Array as a Movie
How to Find Topmost View Controller on Ios
Sending an Http Post Request on Ios
How to Use Scnetworkreachability in Swift
Save String to the Nsuserdefaults
How to Save Picture to Iphone Photo Library
How to Show "Done" Button on iOS Number Pad Keyboard
How to Adjust Font Size to Fit Height and Width of Uilabel
Uidevice Uniqueidentifier Deprecated - What to Do Now
How to Input Currency Format on a Text Field (From Right to Left) Using Swift
Swift: Extra Argument 'Error' in Call
How to Add Nsapptransportsecurity to My Info.Plist File
Libc++Abi.Dylib: Terminating With Uncaught Exception of Type Nsexception (Lldb)