I want to sort an array of NSStrings by length, but then have all strings that are the same length be sub-sorted alphabetically. For example, "cat, hat, zen, nine, rate, tale, access, vanish."
How can I do this? I've been trying to figure out NSSortDescriptors for like an hour and gotten nowhere. I do not know what keys to use in order to sort NSStrings alphabetically or by length. I have sorted them alphabetically using sortedArrayUsingSelector
, but over KevinTTrimm's comment's link, I need to use NSSortDescriptor in order to sort by two metrics, so I need to know the keys.
tl;dr: the key paths you are looking for are "length" and "self" (or "description" or "uppercaseString" depending on what how you want to compare)
As you can see in the documentation for NSSSortDescriptor, a sort descriptor is created "by specifying the key path of the property to be compared". When sorting string by their length, the property on NSString that you are looking for is
length
:Since you want the words to be longer and longer, that sort descriptor should be ascending so that later values have a greater length than the previous value.
Next, to sort the string alphabetically, what you really want is to compare the string directly with the other string. There are a couple of different ways you can do this. For example, the
description
method on NSString (which can be invoked using KVC) is documented to return "This NSString object", meaning the object itself. That would be one option.Other methods you could invoke over KVC are for example
uppercaseString
orlowercaseString
. Using either of these in the sort descriptor will make it an case-insensitive comparison (which either is useful to you, or it isn't).A third way of comparing the string itself directly with the other string is to use the key path
"self"
. You will sometimes see this being used in predicates.In all 3 cases the sort descriptor was made ascending so that letters that appear later in the alphabet come later in the array.
Whichever version of alphabetical sorting that you pick, since you want to sort by length first you would pass the byLength descriptor first and the alphabetical descriptor second.