I'm not sure how far you want to go with this. Finding a Swifty way to do this is not at all easy, because Swift has strict typing and no introspection. Everything about implementing your own sort-by-sort-descriptor method in Objective-C is hard to do in Swift. NSSortDescriptor depends upon key-value coding, which is exactly what is missing from a JSON object because it is a Swift struct. What you need here is an NSObject derivative. If you had stayed with the built-in NSJSONSerialization, that is what you would now have, and the rest would be easy. But you threw that feature away when you went with SwiftJSON instead.
However, just as an example of how to do subsorting by "key" in a special case, let's imagine something like this:
protocol StringSubscriptable {
subscript(which:String) -> String {get}
}
struct Thing : StringSubscriptable {
var p1 : String
var p2 : String
var p3 : String
subscript(which:String) -> String {
switch which {
case "p1": return p1
case "p2": return p2
case "p3": return p3
default: return ""
}
}
}
You see what I've constructed here? It's a pure Swift struct, Thing, that has properties which I've made manually key-value-codable, as it were, by supplying a subscript method that fetches the String value of each of its properties based on the string name of the property.
The StringSubscriptable protocol is then merely a protocol-based way of guaranteeing that Thing has that ability.
Given all that, we can extend Array to do what you're asking for:
extension Array where Element : StringSubscriptable {
mutating func sortByList(list:[String]) {
func sortHelper(a:StringSubscriptable, _ b:StringSubscriptable, _ ix:Int) -> Bool {
let key = list[ix]
if a[key] == b[key] && ix < list.count - 1 {
return sortHelper(a, b, ix + 1)
}
return a[key] < b[key]
}
self.sortInPlace { sortHelper($0, $1, 0) }
}
}
The idea is that you hand sortByList a list of keys and we sort an array of Thing (because it is a StringSubscriptable) based on those keys in order. For each pair, if the first key is enough to determine the outcome, we sort on it, but if the first key gives equal results for this pair, we use the second key instead (that is what subsorting is about).
To illustrate:
let t1 = Thing(p1: "y", p2: "ho", p3: "x")
let t2 = Thing(p1: "z", p2: "ho", p3: "x")
let t3 = Thing(p1: "z", p2: "ho", p3: "a")
var arr = [t1,t2,t3]
arr.sortByList(["p3", "p2", "p1"])
The outcome is
[
Thing(p1: "z", p2: "ho", p3: "a"),
Thing(p1: "y", p2: "ho", p3: "x"),
Thing(p1: "z", p2: "ho", p3: "x")
]
And if you think about it, that's the right answer. First we sort on "p3", so the Thing with p3 value "a" comes first. But for the other two, their p3 values are the same, so we fall back on their p3 values. They are the same as well, so we fall back on their p1 values, and "y" comes before "z".
sortmethod. You know how to do that, right?nameor anis_activeor anageproperty. So how exactly were you expecting this to work?