I have an array of chapters and units.
var chaptersAndUnits: [String] = ["Chapter 2", "Chapter 3", "Chapter 5", "Unit 12", "Chapter 40"]
I am loading them into a UIPickerView
so I order them with chaptersAndUnits = chaptersAndUnits.sorted()
.
However, after this process I get an erratic value: ["Chapter 2", "Chapter 3", "Chapter 40", "Chapter 5", "Unit 12"]
.
I would like to eliminate that Chapter 40
is inserted after Chapter 3
. This also occurs with values like Chapter 22
, it will insert it after Chapter 1
.
What do I need to do to remove these errors? I have looked into regex expressions, but couldn't make them work.
TIA!
This is the expected behaviour. You are comparing strings, not numbers, and "Chapter 40" > "Chapter 5" == true
as "4" > "5"
alphabetically and they are the characters in the same positions in the strings.
If you want to retain the data as strings and order the way you want you will need a custom sorting function. Based on the example strings you could use something like
func bookLessThan(_ lhs: String, _ rhs: String) -> Bool {
let lhsComponents = lhs.components(separatedBy: " ")
let rhsComponents = rhs.components(separatedBy: " ")
return lhsComponents.first! != rhsComponents.first! ? lhsComponents.first! < rhsComponents.first! :
Int(lhsComponents.last!)! < Int(rhsComponents.last!)!
}
var chaptersAndUnits: [String] = ["Chapter 2", "Chapter 3", "Chapter 5", "Unit 12", "Chapter 40"]
let sorted = chaptersAndUnits.sorted(by: bookLessThan)
print(sorted)
// ["Chapter 2", "Chapter 3", "Chapter 5", "Chapter 40", "Unit 12"]
NB: In practice you'd want to safely unwrap all the optionals in case your strings aren't all in the expected format, and then handle that, maybe by returning a false value so they are all at the end.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments