过滤对象内部的领域列表

时间:2019-09-18 12:39:57

标签: ios swift realm

假设Realm中有以下对象:

class Student: Object{
    @objc dynamic var name: String = ""
    let subjects = List<Subject>()
}

class Subject: Object{
    @objc dynamic var name: String = "" 
    @objc dynamic var grade: String = "" // A, B, C, etc
}

我想查询学生,但我只想让subjects的A级成绩。

例如,如果我在Realm中保存了以下内容:

Student 1, subjects = [("math", "A"), ("Science", "B")]
Student 2, subjects = [("math", "C"), ("Science", "A")]
Student 3, subjects = [("math", "B"), ("Science", "C")]

我希望学生的成绩等于A。结果应返回以下内容:

Student 1, subjects = [("math", "A")]
Student 2, subjects = [("Science", "A")]

因此,我最终得到Student类型的Realm Results,对接所有subjects等于A的成绩。 在Realm DB中有可能吗?

3 个答案:

答案 0 :(得分:0)

您不能完全从这里到达-您需要执行一些临时步骤才能获得所需的输出。

首先,您可以使用ANY聚合函数查询列表。因此,要使学生获得任何A级成绩,您都可以这样做。

let studentResults = realm.objects(Student.self).filter("ANY subjects.grade == 'A'")

问题在于,结果是实际上具有任何A级成绩的学生,而返回的结果是 student 对象,其所有成绩都在列表中。

幸运的是,我们还可以将过滤器直接应用于列表。因此,我们将遍历studentResults中返回的每个学生,然后仅针对他们接收的科目和“ A”过滤其list属性。像这样

let studentResults = realm.objects(Student.self).filter("ANY subjects.grade == 'A'")
for student in studentResults {
    let gradeAResults = student.subjects.filter("grade == 'A'")

    for grades in gradeAResults {
        print(student.name, grades.name, grades.grade)
    }
}

外面是

student 1 math A
student 2 Science A

请注意,这还会多次输出学生的姓名,如果他们在多个科目中都获得了“ A”奖。

答案 1 :(得分:0)

我发布了一个单独的答案,它确实回答了问题,但是OP不需要任何形式的迭代。因此,这是使用另一种方法的另一种可能性。

对于这种方法,我们将在所选择的每门科目中添加参考,这些参考链接回该科目的学生。所以学生模型现在看起来像这样

df.groupby('columnA').columnB.agg('max').reset_index()

我们创建一个学生对象:

class Subject: Object{
    @objc dynamic var name: String = ""
    @objc dynamic var grade: String = "" // A, B, C, etc
    @objc dynamic var studentRef: Student!
}

然后创建他们选修的科目和成绩,并参考选择该科目的学生:

let student = Student()
student.name = "Henry"

我们的查询旨在返回所有在任何学科上均获得“ A”级成绩的学生

let subject = Subject()
subject.name = "math"
subject.grade = "A"
subject.studentRef = student

输出将是

let gradeAResults = realm.objects(Subject.self).filter("grade == 'A'")
for subject in gradeAResults {
    print(subject.name, subject.grade, subject.studentRef.name)
}

答案 2 :(得分:-1)

该谓词如何?

SUBQUERY(subjects, $subject, $subject.grade == 'A').@count == subjects.@count

用法:

let students = realm.objects(Student.self).filter("SUBQUERY(subjects, $subject, $subject.grade == 'A').@count == subjects.@count")

它计算A年级的科目数量,然后将其与该学生的科目总数进行比较,如果数量相同,则表示该学生只有A年级科目。

我还没有测试过,但是应该可以。