Reputation: 141
Considering this dictionary:
var studentList = [ "Paul": 5, "Mike": 7, "Ralph": 9, "Graham": 11, "Steve": 12, "Joe": 14, "Truman": 15, "Rick": 16, "Thomas": 17]
And the object below:
class Student {
var name: String
var note: Int
init(name: String, note: Int) {
self.name = name
self.note = note
}
}
I want to iterate through studentList in order to create instances of Student() with the properties name and note implemented by the key and the value of the dictionary to get this result:
student1(name: Paul, note: 5)
student2(name: Mike, note: 9)
....
How should I modify my Student object and what kind function should I use (I've tried with map{} ) to create my Student instances?
Upvotes: 0
Views: 336
Reputation: 797
map(_:) works for your use case, the syntax is just quite complicated for an input structure of type dictionary ($0 is Key, $1 is Value) :
// I want to iterate through studentList in order to create instances of Student() with the properties name and note implemented by the key and the value of the dictionary
// How should I modify my Student object and what kind function should I use (I've tried with map{} ) to create my Student instances?
var students: [Student] = studentList.map { return Student(name: $0, note: $1) }
About your comment, to add categories based on a Student rank, and if you want categories to be instances of class Student, you have to store a shared information between your students, so we will introduce a static variable.
Change your Student class as follow :
class Student {
public enum CategoryType {
case junior
case intermediate
case senior
}
static var studentNotes = [Int]()
var name: String
var note: Int
var category: CategoryType {
get {
let sortedStudentNotes = Student.studentNotes.sorted { $0 > $1 }
var rank = Student.studentNotes.count
for i in 0..<sortedStudentNotes.count {
if sortedStudentNotes[i] == self.note {
rank = (i + 1)
break
}
}
return (1 <= rank && rank <= 3) ? .junior
: ((4 <= rank && rank <= 6) ? .intermediate : .senior)
}
}
init(name: String, note: Int) {
self.name = name
self.note = note
Student.studentNotes.append(note)
}
}
Finally, you can print out Student categories :
// How can I split these result into 3 categories junior, intermediate and senior.
// These 3 categories must be instances of the class Student.
// static var studentNotes: Int[]
students.forEach { print("\($0.name) is \($0.category)") }
Upvotes: 0
Reputation: 236508
If you are not inheriting from NSObject
you should consider using a struct instead of a class. Note that when using a struct it already provides a default initializer and if it matches your map elements (String, Int) you can pass the initializer method to the map method, no need to use a closure:
struct Student {
let name: String
let note: Int
}
let students = studentList.map(Student.init)
If you would like to customize how your struct will print you can make it conform to CustomStringConvertible as suggested by @user28434 and implement a description property:
extension Student: CustomStringConvertible {
var description: String {
return "Name: \(name) - Note: \(note)"
}
}
print(students) // "[Name: Graham - Note: 11, Name: Rick - Note: 16, Name: Steve - Note: 12, Name: Paul - Note: 5, Name: Thomas - Note: 17, Name: Ralph - Note: 9, Name: Joe - Note: 14, Name: Truman - Note: 15, Name: Mike - Note: 7]\n"
Upvotes: 1