How to Sort an Nsmutablearray With Custom Objects in It

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 sorted​Array​Using​Comparator 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



Leave a reply



Submit