I have two arrays of class objects having a common value in each object.
How do I do a join that would be the same as an SQL join?
For example.
Class AM_Template has the following public variables.
class AM_Template
{
public
var SystemID: String = ""
var ULSFileNo: String = ""
var CallSign: String = ""
var Class: String = ""
}
First, the class object AM_line is created using the template and is
var AM_line = AM_Template()
Next, two arrays are created with each record having the form AM_line
var AM0: [AM_Template] = [AM_line.self ]
var AM1: [AM_Template] = [AM_line.self
So now, I need to join AM and AM0 using the variable CallSign.
This is not the same as concatenating. The result of a join, in the SQL manner is an array containing both AM records and AM0 records aligned on the variable le that is in both arrays. There are left joins and right joins, but for now, I am interested in just joins where the values of CallSign are equal.
I’ve looked at the Swift map statement, but haven’t come across anything that actually creates a join as would be similar to an SQL join. How might that be done in Swift?
I'd recommend to use the standard convention of using camelCase for variable names and PascalCase for type names. Also embed code in triple ``` to format it nicely.
Something like that:
public class AMTemplate {
public var systemID: String = ""
public var ulsFileNo: String = ""
public var callSign: String = ""
public var theClass: String = ""
}
var line = AMTemplate()
var line0: [AMTemplate] = [line ]
var line1: [AMTemplate] = [line]
Let me show you a slightly different example, hopefully it'd answer your question:
struct Student {
var id: Int
var name: String
var schoolId: Int?
}
struct School {
var id: Int
var name: String
}
struct StudentSchool {
var student: Student?
var school: School?
}
var students: [Student] = [
Student(id: 1, name: "bob", schoolId: 1),
Student(id: 2, name: "sarah", schoolId: 2),
Student(id: 3, name: "gil", schoolId: 1),
Student(id: 4, name: "adam", schoolId: nil)
]
var schools: [School] = [
School(id: 1, name: "UCL"),
School(id: 2, name: "UWE"),
School(id: 3, name: "UCD")
]
func innerJoin() -> [StudentSchool] {
students.compactMap { student in
let school = schools.first { $0.id == student.schoolId }
guard let school else { return nil }
return StudentSchool(student: student, school: school)
}
}
func leftOuterJoin() -> [StudentSchool] {
students.map { student in
let school = schools.first { $0.id == student.schoolId }
return StudentSchool(student: student, school: school)
}
}
Thank you very much. I am slowly making my way through your comments and translating them to my situation. I understand your comment about the camelCase.
In the example of func innerJoin, is the “student” variable the same as the “struct Student” listed above or is it a new variable. If it is new, how is it defined?
It looks like the “school” variable is a new variable because it is preceded by “let”.
Thank you.
I figured out the answer out the answer to my previous reply asking about the variable "student". It became obvious once I saw the answer. I have your code working in a program and am working to better understand it as i translate it to my project. Thank you.
class Student {
var name: String
init(...) { ... }
}
class School {
var name: String
init(...) { ... }
}
struct StudentSchool { // or class
var student: Student
var school: School
}
var studentSchools: [StudentSchool] = ...
"studentSchools" here would be effectively the inner join result with no extra code needed. Note that in this example "id" fields was not needed (to emphasise that I removed them) as classes have built-in identity.