Arrays 如何计数重复项并将其显示为一个

Arrays 如何计数重复项并将其显示为一个,arrays,swift,dictionary,Arrays,Swift,Dictionary,我有一个名为Students的对象类,其中有Student Name、Contact和Twitter句柄。现在,当我从firebase获取这些数据时,我将其存储在一个数组中,该数组是var students:[Student]=[]。我使用firestore运行查询并将结果存储在数组中,如下所示: let studentObj = Student(dictionary: querySnapShot.data()!) self.students.append(studentObj!) 在quer

我有一个名为
Students
的对象类,其中有
Student Name
Contact
Twitter句柄
。现在,当我从firebase获取这些数据时,我将其存储在一个数组中,该数组是
var students:[Student]=[]
。我使用firestore运行查询并将结果存储在数组中,如下所示:

let studentObj = Student(dictionary: querySnapShot.data()!)
self.students.append(studentObj!)
querySnapShot.data()中,学生的数据可以重复。这意味着可能会有相似的学生出现不止一次

我想对重复的学生进行计数,例如,如果数据中的
Ava
是三倍,则应进行计数,并在tableview单元格中显示为
Ava(3)
。我使用字典
var studentCapCount=[String:Int]()
和函数:

func countStudents(studentArray: [Student]) {
    for item in studentArray {

        studentCapCount[item.name] = studentCapCount[item.name] ?? 0 + 1
    }
    self.tableView.reloadData()
}
问题:

struct Student {

    var name: String
    var contact: String
    var twitter: String


    var dictionary: [String: Any] {
        return [
            "name": name,
            "contact": contact,
            "twitter": twitter
        ]
    }
}

extension PoliticianMarker {
    init?(dictionary: [String: Any]) {
        let name = dictionary["name"] as? String,
        let contact = dictionary["contact"] as? String,
        let twitter = dictionary["twitter"] as? String
            else {
            return nil
        }
        self.init(name: name, contact:contact, twitter:twitter)
    }
}
该功能计数正确,但在显示时出现问题。因为我只使用了
item.name
,所以我不知道如何在
cellForRowAt
tableView
方法中显示学生姓名联系人推特。比如我应该在这里写什么:

    cell.textLabel?.text =  ??
    cell.detailTextLabel?.text = "Contact: \(students[indexPath.row].contact) | Twitter: \(students[indexPath.row].twitter)"
如果我在
numberOfRowsInSection
中返回
students.count
,这是一个问题,因为它还将包含重复的值count,但如果我返回
studentCapCount.count
这也是一个问题,因为我无法打印
detailTextLabel?.text
,因为行数太多

学生班级代码:

struct Student {

    var name: String
    var contact: String
    var twitter: String


    var dictionary: [String: Any] {
        return [
            "name": name,
            "contact": contact,
            "twitter": twitter
        ]
    }
}

extension PoliticianMarker {
    init?(dictionary: [String: Any]) {
        let name = dictionary["name"] as? String,
        let contact = dictionary["contact"] as? String,
        let twitter = dictionary["twitter"] as? String
            else {
            return nil
        }
        self.init(name: name, contact:contact, twitter:twitter)
    }
}

Student
Hashable
相一致,并实现
=
散列(到:)
方法

struct Student: Hashable {
    var name: String
    var contact: String
    var twitter: String

    func hash(into hasher: inout Hasher) {
        hasher.combine(name)
        hasher.combine(contact)
        hasher.combine(twitter)
    }

    static func == (lhs: Student, rhs: Student) -> Bool {
        return lhs.name == rhs.name && lhs.contact == rhs.contact && lhs.twitter == rhs.twitter
    }
}
现在,您可以使用
字典的
init(分组:按:)
对重复的
学生
实例进行分组,即

var students = [Student(name: "Alex", contact: "1234", twitter: "XYZ"), Student(name: "Alex", contact: "1234", twitter: "XYZ"), Student(name: "Mike", contact: "98765", twitter: "XYZ"), Student(name: "Mike", contact: "09876", twitter: "PQR")]

let dict = Dictionary(grouping: students, by: { $0.hashValue })
接下来,使用
compactMap(:)
dict
获取
学生的
,如下所示

students = dict.compactMap({
    var countText = ""
    if $0.value.count > 1 {
        countText = " x\( $0.value.count)"
    }
    var student = $0.value.first
    student?.name += countText
    return student
})

最后,使用
学生
作为您的
tableView的
数据源

如果有多个学生的名字相同,联系方式不同,twitter?@PGDev也可能发生这种情况,该怎么办。有没有办法在
学生
对象上执行此操作?否则,我将不得不在后端进行此更改。此操作非常有效。只有一个问题,我是否可以修改您共享的代码,以显示带有名称标签的
x2
。假设从您给出的代码示例中,我需要显示两次出现的Alex x2。