3

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!

asked Dec 24, 2021 at 10:39
6
  • So you want to sort the users array, not the contactArray? Can you show your desired result? Commented Dec 24, 2021 at 10:45
  • I want to sort users firstname but I have contact array. Yes showing result Commented Dec 24, 2021 at 10:46
  • Please check updated. Let me know if you need any other details. Commented Dec 24, 2021 at 10:50
  • I'm not asking about what you want to sort by. I'm asking which array you want to change. Your desired result seems to be the same as what the array contains originally? Do you perhaps mean that you want "Yash" to come before "Yogesh"? Commented Dec 24, 2021 at 10:51
  • Yes Here we have contact array first I sorted using alphabet and then we need to sort the contact users on bases of firstname. Yes first comes Yash then Yogesh. The same thing for all section users. contacts.users.sort firstname like this! Commented Dec 24, 2021 at 10:53

1 Answer 1

2

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 }) } )
answered Dec 24, 2021 at 10:55

2 Comments

Aww! Great understood! so now I have to assign this fullSorted to my contactArray?
You could do this immediately (i.e. replace let fullySorted by contactArray), assuming it's a var and not a let.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.