迭代字典以获取最高GPA

时间:2019-01-23 00:38:58

标签: arrays swift dictionary

家庭作业问题。 我需要遍历一系列字典以获得最高的gpa并打印学生的名字和姓氏。我在访问字典条目的gpa字段时遇到问题。

// Task 6
var highestGPA = 0.0
var students : [[String:Any]] =
    [["firstName": "John", "lastName": "Wilson", "gpa": 2.4],
     ["firstName": "Nancy", "lastName": "Smith", "gpa": 3.5],
     ["firstName": "Michael", "lastName": "Liu", "gpa": 3.1]]

for index in students   {
    if let val = (_,_,"gpa":key) {
        highestGPA = val
    }
}

预期结果将是遍历字典数组并获得最高gpa。 实际结果是编译错误“二进制运算符'>'无法应用于类型(,String)和Double的操作数。 因此,似乎是在获取字符串“ gpa”而不是gpa的值

编辑:我还尝试了以下代码来获取“ gpa”字段中的值并将其转换为双精度。

for index in students   {
    myGPA = Double(index["gpa"])
    if myGPA > highestGPA   {
        highestGPA = myGPA
    }        
}

我收到编译错误:错误:无法使用类型为“(Any?)”的参数列表调用类型为“ Double”的初始化程序     myGPA = Double(index [“ gpa”])

3 个答案:

答案 0 :(得分:3)

您可以使用Array函数max来确定GPA最高的学生。

let student = students.max { $0["gpa"] as? Double ?? 0 < $1["gpa"] as? Double ?? 0 }

print(student?["firstName"]) // Nancy
print(student?["gpa"]) // 3.5

答案 1 :(得分:1)

由于您已在字典中将值标记为Any,因此在使用它时必须将其as? Double下转换。下面的代码解决了您的问题。

var highestGpa = 0.0
var highestPerformingStudent = students[0]
for student in students {
    if let gpa = student["gpa"] as? Double {
        if (gpa > highestGpa) {
            highestGpa = gpa
            highestPerformingStudent = student
        }
    }
}

print(highestPerformingStudent)
// prints ["firstName": "Nancy", "lastName": "Smith", "gpa": 3.5]

答案 2 :(得分:1)

正如@Alexander在评论中建议的那样,最好使用一个struct来保存您的学生姓名和gpa数据。然后,您将具有强类型成员,而不必将Any强制转换为StringDouble。结构自动提供一个接受每个成员的初始化程序。这样可以避免在初始化Student数据数组时打错字。

通过制作struct CustomStringConvertible并实现var description,可以很好地格式化struct的输出。

然后,您可以使用max(by:)来找到Student,其中gpa是最大的Student,方法是传递一个定义如何比较两个struct Student: CustomStringConvertible { var firstName: String var lastName: String var gpa: Double var description: String { return "\(firstName) \(lastName) (\(gpa))" } } let students: [Student] = [ Student(firstName: "John", lastName: "Wilson", gpa: 2.4), Student(firstName: "Nancy", lastName: "Smith", gpa: 3.5), Student(firstName: "Michael", lastName: "Liu", gpa: 3.1) ] if let student = students.max(by: { $0.gpa < $1.gpa }) { // Print the student information print(student) // Print the student's name print("\(student.firstName) \(student.lastName)") // Print the highest gpa print(student.gpa) } 记录的闭包。

Nancy Smith (3.5)
Nancy Smith
3.5

输出:

Student

初始化map()数据的替代方法:

按照@LeoDabus的建议,您可以使用元组数组和students来初始化let students = [ ("John", "Wilson", 2.4), ("Nancy", "Smith", 3.5), ("Michael", "Liu", 3.1) ].map(Student.init) 数组,如下所示:

class X:
    @property
    def foo(self):
        r = calculate_something()
        self.foo = r
        return r

这样做的好处是消除了视觉混乱,并节省了键入内容,但不显式显示正在初始化的字段。