Programming in Swift: Functions & Types, Episode 34: Challenge: Methods | raywenderlich.com

Practice what you have learned about using methods through this series of hands-on coding challenges.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/28433240-programming-in-swift-functions-types/lessons/34

hi !
I’m having a rough time to understand what is returned to what in the following closure:

mutating func curveGrades() {
		guard let highest  = getHighestGrade() else { return }
		let difference = 100 - highest
		students = students.map{ student in var student = student
			student.grade += difference
			return student
		}.sorted{ $0.grade > $1.grade }
	}
}

So, going step by step:

  • The first students is the thingy of the struct, the one we want to modify.
  • Then this is set equal to the result (the returned value) of .map
    -We name student each one of the contained elements of the map
  • in which we declare a var student = student
  • and its this 'just declared ’ student, whom .grade we access and modify
  • and then we return this student to the first student of closure or to the
    var student = student ??
    and finally why we need to set students of the struct = students.map{...} since we have mutating and var everywhere??
    Could all this be easier if somehow we had inout and & ?

Hope all the above makes sense :slight_smile:

Hi! It looks like you’ve understood this nearly perfectly :+1:

and then we return this student to the first student of closure or to the var student = student ??

The student you’re returning in map is the variable student created inside the closure. It can get confusing with a bunch of things all named the same, for sure. It might be easier to follow if it was written like this:

mutating func curveGrades() {
  guard let highest = getHighestGrade() else { return }
  let difference = 100 - highest

  let curvedStudents: [Student] = students.map { student in
    var curvedStudent = student
    curvedStudent.grade += difference
    return curvedStudent
  }

  students = curvedStudents.sorted { $0.grade > $1.grade }
}

And for your other question:

Could all this be easier if somehow we had inout and & ?

Not in this case, that I can think of. The trouble is that any time you loop over collections like you’re doing here, you’re working with a local immutable copy inside of the new scope. That’s true whether you’re doing it with map or a traditional for loop. Swift doesn’t currently have a “map in place” kind of method with an inout argument, which I agree would make this whole example much shorter!

1 Like