代码之家  ›  专栏  ›  技术社区  ›  Chaudhry Talha

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

  •  0
  • Chaudhry Talha  · 技术社区  · 5 年前

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

    let studentObj = Student(dictionary: querySnapShot.data()!)
    self.students.append(studentObj!)
    

    里面 querySnapShot.data() 学生的数据可能是重复的。这意味着可能会有类似的学生出现多次。

    我想数一数那些重复的学生,例如,如果 Ava 是数据中的三倍,它应该将其计数并显示为 Ava (3) 在tableview单元格中。我是用字典查的 var studentCapCount = [String: Int]() 以及一个函数:

    func countStudents(studentArray: [Student]) {
        for item in studentArray {
    
            studentCapCount[item.name] = studentCapCount[item.name] ?? 0 + 1
        }
        self.tableView.reloadData()
    }
    

    问题:

    该功能正在正确计数,但在显示方面存在问题。因为我只使用 item.name 所以我不知道该怎么表现 学生姓名 , 接触 推特 在里面 cellForRowAt 方法 tableView 。比如我应该在这里写什么:

        cell.textLabel?.text =  ??
        cell.detailTextLabel?.text = "Contact: \(students[indexPath.row].contact) | Twitter: \(students[indexPath.row].twitter)"
    

    如果我回来 students.count 在里面 numberOfRowsInSection 这是一个问题,因为它还将包括重复值计数,但如果我这样做 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)
        }
    }
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   PGDev    5 年前

    符合要求 Student Hashable 并实施 == hash(into:) 方法,

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

    现在,您可以对副本进行分组 学生 实例使用 Dictionary's init(grouping:by:) ,即。

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

    接下来,拿到 students dict 使用 compactMap(_:) 像这样,

    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's dataSource .