Sort UITableView in Russian alphabetical order - iphone

I'm a noob, and I'm sorry because the question is really stupid. I have An NSArray which contains titles for UITableView rows in NSDictionaries in Russian and I need to sort these titles in alphabetical order. How can I do it?
Help me, please.
Thanks in advance!

On iOS 4.0 and later, you can use a sort descriptor. Assuming title is the key under which your title strings are stored in the dictionaries:
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:
[NSArray arrayWithObject:
[NSSortDescriptor sortDescriptorWithKey:#"title"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)]]];
Another option is to use a block-based sort method:
NSArray *sortedArray = [myArray sortedArrayUsingComparator:^(id obj1, id obj2) {
NSString *string1 = [(NSDictionary *)obj1 objectForKey:#"title"];
NSString *string2 = [(NSDictionary *)obj2 objectForKey:#"title"];
return [string1 localizedCaseInsensitiveCompare:string2];
}];
If you need your app to run on iOS 3.1.3 and earlier, however, you can either:
write a comparison method as a category on NSDictionary and pass it to -sortedArrayUsingSelector:, or
write a comparison function and pass it to -sortedArrayUsingFunction:context:.
In each case, your method or function's body will be essentially the same as the body of the block in the second example above. The NSArray class reference contains examples of both techniques.

I think this will sort your array:
NSArray *sortedArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];

Related

Sort an NSMutableArray / Dictionary with several objects

I am having a problem that I think I am overcomplicating.
I need to make either an NSMutableArray or NSMutableDictionary. I am going to be adding at least two objects like below:
NSMutableArray *results = [[NSMutableArray alloc] init];
[results addObject: [[NSMutableArray alloc] initWithObjects: [NSNumber numberWithInteger:myValue01], #"valueLabel01", nil]];
This gives me the array I need but after all the objects are added I need to be able to sort the array by the first column (the integers - myValues). I know how to sort when there is a key, but I am not sure how to add a key or if there is another way to sort the array.
I may be adding more objects to the array later on.
Quick reference to another great answer for this question:
How to sort NSMutableArray using sortedArrayUsingDescriptors?
NSSortDescriptors can be your best friend in these situations :)
What you have done here is create a list with two elements: [NSNumber numberWithInteger:myValue01] and #"valueLabel01". It seems to me that you wanted to keep records, each with a number and a string? You should first make a class that will contain the number and the string, and then think about sorting.
Doesn't the sortedArrayUsingComparator: method work for you? Something like:
- (NSArray *)sortedArray {
return [results sortedArrayUsingComparator:(NSComparator)^(id obj1, id obj2)
{
NSNumber *number1 = [obj1 objectAtIndex:0];
NSNumber *number2 = [obj2 objectAtIndex:0];
return [number1 compare:number2]; }];
}

How to sort an NSArray full of EKCalendars by the title

I've got a NSArray with a bunch of EKCalendar Objects in it. I need to sort them alphabetically. I'm new to selectors but I think I need something like...
NSArray *array = [otherArray sortedArrayUsingSelector:#selector('localizedCaseInsensitiveCompare:title')];
Cheers
You cannot do it that way. Instead do the following:
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {
EKCalendar *cal1 = (EKCalendar *)obj1;
EKCalendar *cal2 = (EKCalendar *)obj2;
return [cal1.title localizedCaseInsensitiveCompare:cal2.title];
}];
Edit - an explanation:
-sortedArrayUsingComparator takes what is called a 'block' (an inline function) that must return an NSComparisonResult. All the hard work is done for you, as your block is run for as many pairs of objects as is needed to establish the correct order. Then all this does is cast each object type to an EKCalendar and then compare the two titles. You can adapt this to work for any type of object.
This should do the trick:
NSMutableArray *sortDescriptors = [NSMutableArray array];
NSSortDescriptor *sortByTitleAsc = [[[NSSortDescriptor alloc] initWithKey:#"title" ascending:YES] autorelease];
[sortDescriptors addObject:sortByTitleAsc];
NSArray *arraySortedByTitle = [otherArray sortedArrayUsingDescriptors:sortDescriptors];
No, you don't want to use a selector, you want to use a key path, which requires a sort descriptor. You can't append an arbitrary property name to a selector name. The selector must exactly match the method name. Otherwise you just get nothing (nil/NULL/0) for the selector.
id sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"title" ascending:YES]]];
For the sake of completeness and and timeliness, here’s the Swift 4 version:
let store = EKEventStore()
let calendars = store.calendars(for: .event)
let calendarsSorted = calendars.sorted { $0.title.localizedCaseInsensitiveCompare($1.title) == ComparisonResult.orderedAscending }
By the way, please don’t forget to request access to the store by calling store.requestAccess(to:completion:) before accessing the store’s data.

Getting an NSArray of a single attribute from an NSArray

I am facing a very regular scenario.
I have an NSArray which has object of a custom type, say Person. The Person class has the attributes: firstName, lastName and age.
How can I get an NSArray containing only one attribute from the NSArray having Person objects?
Something like:
NSArray *people;
NSArray *firstNames = [people getArrayOfAttribute:#"firstName" andType:Person.Class]
I have a solution of writing a for loop and fill in the firstNames array but I don't want to do that.
NSArray will handle this for you using KVC
NSArray *people ...;
NSArray *firstName = [people valueForKey:#"firstName"];
This will give you an array of the firstName values from each entry in the array
Check out the filterUsingPredicate: method in NSMutableArray, basically you create a NSPredicate object that will define how the array will be filtered.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html#//apple_ref/doc/uid/TP40001794-CJBDBHCB
This guide will give you an overview, and has a section for dealing with arrays.
You can also use block based enumeration:
NSArray *people; // assumably has a bunch of people
NSMutableArray *firstNames = [NSMutableArray array];
[people enumerateObjectsUsingBlock:
^(id obj, NSUInteger idx, BOOL*flag){
// filter however you want...
[firstNames addObject:[Person firstName]];
}];
The benefit is it is fast and efficient if you have a bunch of people...

Sorting an NSArray of NSDictionary

I have to sort an array of dictionaries but I have to order by an object in the dictionaries.
Use NSSortDescriptors with -sortedArrayUsingDescriptors:. For the key path, pass in the dictionary key, followed by the object's key(s) by which you want to sort. In the following example, you have an array of dictionaries and those dictionaries have a person under "personDictionaryKey", and the "person" has a "lastName" key.
NSSortDescriptor * descriptor = [[[NSSortDescriptor alloc] initWithKey:#"personInDictionary.lastName"
ascending:YES] autorelease]; // 1
NSArray * sortedArray = [unsortedArray sortedArrayUsingDescriptors:
[NSArray arrayWithObject:descriptor]];
1 - In 10.6 there are class convenience methods for creating sort descriptors but as bbum's answer says, there are now blocks-enabled sorting methods and I'm betting they're a lot faster. Also, I noticed your question is for iOS, so that's probably irrelevant. :-)
To rephrase; you want to sort the array by comparing dictionary contents? (I.e. you know you can't sort a dictionary's contents, right?)
As Joshua suggested, use NSSortDescriptor and sortedArrayUsingDescriptors:. This is quite likely the best solution; at least the most straightforward.
There are other ways, too.
Assuming you are targeting iOS 4.0, then you can use sortedArrayUsingComparator: and pass a block that'll do the comparison of the two dictionary's contents.
If you are targeting iOS 3.x (including the iPad), then you would use sortedArrayUsingFunction:context:.
Or, as Joshua suggested, use NSSortDescriptor and sortedArrayUsingDescriptors:
All are quite well documented, with examples.
here is an implementation with custom objects instead of dictionaries:
ArtistVO *artist1 = [ArtistVO alloc];
artist1.name = #"Trentemoeller";
artist1.imgPath = #"imgPath";
ArtistVO *artist2 = [ArtistVO alloc];
artist2.name = #"ATrentemoeller";
artist2.imgPath = #"imgPath2";
ArtistVO *artist3 = [ArtistVO alloc];
artist3.name = #"APhextwin";
artist3.imgPath = #"imgPath2";
//NSLog(#"%#", artist1.name);
NSMutableArray *arr = [NSMutableArray array];
[arr addObject:artist1];
[arr addObject:artist2];
[arr addObject:artist3];
NSSortDescriptor *lastDescriptor =
[[[NSSortDescriptor alloc]
initWithKey:#"name"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray * descriptors =
[NSArray arrayWithObjects:lastDescriptor, nil];
NSArray * sortedArray =
[arr sortedArrayUsingDescriptors:descriptors];
NSLog(#"\nSorted ...");
NSEnumerator *enumerator;
enumerator = [sortedArray objectEnumerator];
ArtistVO *tmpARt;
while ((tmpARt = [enumerator nextObject])) NSLog(#"%#", tmpARt.name);

how to sort array of strings

I create an array with string names as shown below
NSMutableArray *strings = [[NSMutableArray alloc]init];
[string addObject:#"string1"];
[string addObject:#"string2"];
[string addObject:#"string3"];
[string addObject:#"string4"];
and I create a button. Whenever I click the button the strings are exchanged how can I do this?
EDIT:
Looks like you do not really lack basic knowledge. You can call this method in NSArray after you add your objects:
This method is the simplest way to do your job:
NSArray *sortedStrings = [strings sortedArrayUsingSelector:#selector(compare:)];
More about sortedArrayUsingSelector:
You can see NSArray class reference about following methods.
Sorting
sortedArrayHint
sortedArrayUsingFunction:context:
sortedArrayUsingFunction:context:hint:
sortedArrayUsingDescriptors:
sortedArrayUsingSelector:
sortedArrayUsingComparator:
sortedArrayWithOptions:usingComparator:
As for your problem, you can sort strings by [strings sortedArrayUsingSelector:#selector(compare:)].