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。