【问题标题】:Nested Sort in Struct Array in Swift 5Swift 5中结构数组中的嵌套排序
【发布时间】:2022-01-25 00:49:36
【问题描述】:

这是我的模型的样子

struct ContactModel{
    var alphabet: String
    var users: [UserModel]
}

struct UserModel{
    var firstname: String
    var lastname: String
}

使用sort 按字母顺序排序在这里工作正常是代码:

contactArray.sort{ $0.alphabet < $1.alphabet }

现在,我想根据UserModel firstname 对升序或降序进行排序 我尝试使用嵌套排序,但给了我不同的错误,例如

Comparable and Binary operator '<' cannot be applied to two '[UserModel]' operands

我在 StackOverflow 上搜索了这方面的内容,但没有找到嵌套排序和操作数错误解决方案。

我试过这种方式

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
            }

但它不起作用。我在这里无法进行嵌套排序的唯一问题是要对 UserModel 的名字和我们有 ContactModel 数组进行排序

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()
        }
    }

数组包含这个

 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")
            ])
        ]
    }

结果:

字母部分排序工作正常需要现在使用名字对用户进行排序Yash首先是Yogesh

任何建议表示赞赏。谢谢!

【问题讨论】:

  • 所以你想排序users数组,而不是contactArray?你能展示你想要的结果吗?
  • 我想对用户名进行排序,但我有联系人数组。是的,显示结果
  • 请检查更新。如果您需要任何其他详细信息,请告诉我。
  • 我不是在问你想要排序什么。我在问您要更改哪个数组。您想要的结果似乎与数组最初包含的结果相同?您的意思是想让“Yash”出现在“Yogesh”之前?
  • 是的,这里我们首先有联系人数组,我使用字母排序,然后我们需要根据名字对联系人用户进行排序。是的,首先是 Yash,然后是 Yogesh。所有部分用户都一样。像这样的contacts.users.sort firstname!

标签: arrays swift sorting multidimensional-array


【解决方案1】:

下面的代码首先根据字母对ContactModel 数组进行排序。然后,它将这个排序后的数组映射到一个新数组,其中UserModel 数组也被排序。

contactArray.sort { $0.alphabet < $1.alphabet }
let fullySorted = contactArray.map( { ContactModel(alphabet: $0.alphabet, users: $0.users.sorted { $0.firstname < $1.firstname }) } )

mapsort 函数也可以交换,即首先映射到一个新数组,然后根据字母表排序。 原始数组:

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")
    ])
]

将变为(Yash 和 Yogesh 现在按字母顺序排列):

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")
    ])
]

如果有另一个ContactModelalphabet = "A",那么这将是contactArray 中的第一个。

如果你真的想要的话,甚至可以将其缩减为一行代码。但是,我不推荐它,因为排序和映射对于不熟悉它的人来说很难很容易阅读。

// 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 }) } )

【讨论】:

  • 哇!很好理解!所以现在我必须将此 fullSorted 分配给我的contactArray?
  • 您可以立即执行此操作(即将let fullySorted 替换为contactArray),假设它是var 而不是let
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-26
  • 2015-08-14
相关资源
最近更新 更多