2

Hi I have the following

class MyClass {
  var myString: String?
}

var myClassList = [String: MyClass]()

I would like to sort this array alphabetically by the myString variable in Swift 3 any pointers?

Adil Ansari
  • 83
  • 2
  • 7
  • 1
    `myClassList` is a dictionary not an array. I recommend you get the data structures correct before moving on to sorting. – par Dec 13 '16 at 02:53
  • `myClassList.sorted{($0.value.myString ?? "") < ($1.value.myString ?? "")}` – Leo Dabus Dec 13 '16 at 02:53

3 Answers3

5

As mentioned above, you have a dictionary, not tuples. However, Dictionaries do indeed have a sorted(by:) method that you can use to sort an array of Key/Value pair tuples. Here's an example:

var m: [String: Int] = ["a": 1]
let n = m.sorted(by: { (first: (key: String, value: Int), second: (key: String, value: Int)) -> Bool in
  return first.value > second.value
})

That's expanded to show the full signature of the closure, however easily shorthanded to:

let n = m.sorted(by: {
  return $0.value > $1.value
})

Additionally, you can also perform other enumerations over Dictionaries

m.forEach { (element: (key: String, value: Int)) in
  print($0.value)
}

All of this is due to the Collection and sequence protocol hierarchies in Swift, they're some pretty nice abstractions.

apocolipse
  • 619
  • 6
  • 11
  • if you remove the parentheses you can omit the `by:`. You can also omit the `return`keyword. BTW He said he wants to sort by myString property – Leo Dabus Dec 13 '16 at 05:54
  • Right in this case I wanted the strings alphabetized. – Adil Ansari Dec 13 '16 at 07:17
  • @LeoDabus Check xcode, Dictionaries only have `sorted(by:)`, meaning you can't omit the `by` when enclosing in parens, you can however if you're using trailing closure syntax (Though stylistically that isn't preferred for things like sort/map/filter) – apocolipse Dec 13 '16 at 21:53
3

Cool problem! Though i'd like to point out first that [String: MyClass] is a Dictionary and not at Tupule.

Swift does, however, support Tupules. The syntax for your tupule would look like so:

var tupule: (String, MyClass) = (foo, bar)

You would then need to make an Array of them:

var tupules:[(String, MyClass)] = [(foo, bar), (up, dog)]

Then you could sort that array:

tupules.sort({ $0[1].myString > $1[1].myString })

though you should probably define a more robust sort mechanism.

These are the contents of the sort closure:

$0 is the one of the objects for which needs to be compared, $1 is the other. $0[1] and $1[1] accesses the objects' 1 index, in this case, as defined in your tupule, it is your custom object MyClass

Hope this helps.

esreli
  • 4,993
  • 2
  • 26
  • 40
0

Swift version 5.2.4

let arr = [(0, 5), (1, 2), (2, 4), (3, 1), (4, 3)] // -> [(3, 1), (1, 2), (4, 3), (2, 4), (0, 5)]
let sorted = arr.sorted{ $0.1 < $1.1 }
hectorsvill
  • 681
  • 8
  • 7