NSMutableArray Sorting Using a Selector

I have googled searching for stackoverflow with no satisfying answers.

The documentation states that:

sortUsingSelector: sorts the arrays of elements in ascending order, as determined by the comparison method specified by this selector.

  • (are canceled) sortUsingSelector: (SEL) comparator Comparator parameter A selector that specifies the comparison method to use to compare the elements in the array. a comparator message is sent to each object in the array and has a single argument from another object in the array. The comparator method should return NSOrderedAscending if the array is less than the argument, NSOrderedDescending if the array is larger than the argument, and NSOrderedSame if they are equal.

I am trying to understand how this works. Therefore, if I have this method in my object inside an array class:

- (NSComparisonResult) compareNames: (id) element { return [userName compare: [element userName]]; } 

And execute it with

 [myArray sortUsingSelector:@selector(compareNames:); 

It works. The problem is that I do not know why this works. The return type for NSComparisonResult is either ascending, the same, or descending. From what I get from reading the documentation, the compareNames method is sent to each object in myArray and compares the selected property of the object (in this case, the username) with the username in another object inside the same array. (Like array [0] is compared with array [1]). I want to know how this whole process goes.

Update 1: Sort Algorithm for Multiple Keys

I missed! compared. This should be correct:

 NSComparisonResult res; res = [[self userName] compare: [element userName]]; if(res == NSOrderedSame) res = [[self email] compare: [element email]]; return res; 

As for sorting in downstream, you can use switch or if to return the value of NSComparisonResult, replacing "return res" with this:

 switch (res) { case NSOrderedAscending: return NSOrderedDescending; break; case NSOrderedDescending : return NSOrderedAscending; break; default: return NSOrderedSame; break; }*/ 
+4
source share
2 answers

To answer your subqueries in the comments:

Do you always need to sort in ascending order? - NSOrderedAscending and NSOrderedDescending are simply symbolic here, you can think of them as an “object before an argument” and “an object comes after an argument” in sort order. For instance. if you save the NSNumber array, then "1 compareTo: 2" should return NSOrderedAscending if you want to sort with increasing value, and NSOrderedDescending if you want to sort with decreasing value.

How do you sort multiple keys? - Any sorting algorithm should only know if there is one element before, after, or at the same position as another. How you determine what is up to you. To use two sort keys, then in the pseudo-code the algorithm:

 To compare item1 and item2 order = [item1.key1 compareTo:item2.key1]; if (order == NSOrderedSame) order = [item1.key2 compareTo:item2.key2]; return order 

If necessary, increase the number of keys or more complex comparisons.


Follow the comments:

Sorry, but the provided algorithm performs 2-key sorting, and in general, combining keys may not be wasteful.

In English, sorting by two keys is as follows: first, compare the first key of each object if they are not equal, and then return their order. If they compare the same ones, then go and compare the second key of each object and return their order.

This is exactly what pseudo code does above.

Combining multiple keys is problematic for several reasons:

  • You must combine them with a delimiter that cannot happen in keys. As a simple example, consider sorting by first name, last name, when you have two people “jack yolander” and “jacky olander” - naive joining produces a “jack-linlander” for both, and they will sort the same way. Thus, you need a delimiter that cannot be found in any of the keys.

  • If the keys are of different types, for example. string and number, you end up converting them all into strings to combine — wasteful and possibly even inaccurate.

  • Just combining them is useless - you generate objects that you do not need.

Etc. Just compare the keys in pairs until you find two that are different or fall into the last pair. Works for any number of keys of any type and is not wasteful.

+4
source

sortUsingSelector will use Quicksort or a similar sorting algorithm to sort the array. Sorting algorithms should be able to compare two elements in a sortable collection and determine where they should be displayed relative to each other in sorted order. Should A appear before B, after B, or right next to it? Your own sorting method ( compareNames in your example) is a sorting algorithm that should determine this ordering.

Look at the Wikipedia entry for sorting algorithms for some background on this.

You will not find much on the Internet about this if you are looking for a search, for example. "SortUsingSelector". This is not an Objective-C problem; almost all programming languages ​​have sorting procedures that use a custom comparison function to sort.

+1
source

Source: https://habr.com/ru/post/1342089/


All Articles