Here its my model looks like
struct ContactModel{
var alphabet: String
var users: [UserModel]
}
struct UserModel{
var firstname: String
var lastname: String
}
Using sort
alphabetically sorting working fine here Is the code:
contactArray.sort{ $0.alphabet < $1.alphabet }
Now, I want to sort ascending or descending order on bases of UserModel
firstname
I try with nested sorting but giving me different errors like
Comparable and Binary operator '<' cannot be applied to two '[UserModel]' operands
I search on StackOverflow regarding this but haven't find nested sorting and operands error solution.
I tried this way
let sortedStudents = contactArray.sorted { (lhs: ContactModel, rhs: ContactModel) -> Bool in
let users1 = lhs.users.sorted(by: {
$0.firstname.lowercased() < $1.firstname.lowercased()
})
let users2 = rhs.users.sorted(by: {
$0.firstname.lowercased() < $1.firstname.lowercased()
})
return users1 < users2
}
But its not working. The only problem here that I am not able to do nested sort here want to sort firstname of UserModel and the We have ContactModel
Array
var contactArray = [ContactModel](){
didSet{
contactArray.sort{ $0.alphabet < $1.alphabet } //Simple Sort working fine.
let sortedStudents = contactArray.sorted { (lhs: ContactModel, rhs: ContactModel) -> Bool in
let users1 = lhs.users.sorted(by: {
$0.firstname.lowercased() < $1.firstname.lowercased()
})
let users2 = rhs.users.sorted(by: {
$0.firstname.lowercased() < $1.firstname.lowercased()
})
return users1 < users2
}
self.tableView.reloadData()
}
}
Array Contains this
func getAllContacts() -> [ContactModel]{
return [
ContactModel(alphabet: "B", users: [
UserModel(firstname: "Bhaswar", lastname: "Patel"),
UserModel(firstname: "Bunty", lastname: "Patel")
]),
ContactModel(alphabet: "N", users: [
UserModel(firstname: "Nilesh", lastname: "Darji")
]),
ContactModel(alphabet: "Y", users: [
UserModel(firstname: "Yogesh", lastname: "Patel"),
UserModel(firstname: "Yash", lastname: "Patel")
])
]
}
Results:
Alphabetic section sorting working fine need to sort users now using firstname for this Yash
is comes first then Yogesh
Any suggestion appreciated. Thanks!
CodePudding user response:
The code below is sorting the ContactModel
array based on the alphabet first. Then, it maps this sorted array to a new array where the UserModel
array is sorted as well.
contactArray.sort { $0.alphabet < $1.alphabet }
let fullySorted = contactArray.map( { ContactModel(alphabet: $0.alphabet, users: $0.users.sorted { $0.firstname < $1.firstname }) } )
The map
and sort
functions could also be swapped, i.e. first mapping to a new array and then sorting based on the alphabet.
The original array:
var contactArray = [
ContactModel(alphabet: "B", users: [
UserModel(firstname: "Bhaswar", lastname: "Patel"),
UserModel(firstname: "Bunty", lastname: "Patel")
]),
ContactModel(alphabet: "N", users: [
UserModel(firstname: "Nilesh", lastname: "Darji")
]),
ContactModel(alphabet: "Y", users: [
UserModel(firstname: "Yogesh", lastname: "Patel"),
UserModel(firstname: "Yash", lastname: "Patel")
])
]
will become (Yash and Yogesh are now alphabetically ordered):
var contactArray = [
ContactModel(alphabet: "B", users: [
UserModel(firstname: "Bhaswar", lastname: "Patel"),
UserModel(firstname: "Bunty", lastname: "Patel")
]),
ContactModel(alphabet: "N", users: [
UserModel(firstname: "Nilesh", lastname: "Darji")
]),
ContactModel(alphabet: "Y", users: [
UserModel(firstname: "Yash", lastname: "Patel"),
UserModel(firstname: "Yogesh", lastname: "Patel")
])
]
If there would be another ContactModel
with alphabet = "A"
, then this would've been the first one in the contactArray
.
You could even reduce it to a single line of code if you really want. However, I wouldn't recommend it because sorting, and mapping can become hard to read quite easily for people that aren't familiar with it.
// Single line of code solution (I wouldn't recommend this because of readability)
let fullySorted = contactArray.sorted { $0.alphabet < $1.alphabet }.map( { ContactModel(alphabet: $0.alphabet, users: $0.users.sorted { $0.firstname < $1.firstname }) } )