我有三个对象嵌套在这样的列表中:
class Canteen: Object {
dynamic var name: String?
let lines = List<Line>()
}
class Line: Object {
dynamic var name: String?
let meals = List<Meal>()
}
class Meal: Object {
dynamic var name: String?
dynamic var vegan: Bool = false
}
获取所有食堂和食物的所有食堂都没有问题。我现在正在做的是:
let predicate = NSPredicate(format: "name == %@", selectedCanteenType.rawValue)
canteens = realm.objects(Canteen).filter(predicate)
但现在我只需要素食主义者的饭菜。因此,我希望获得所有线路的选定食堂,但只有纯素食品。这是否可以在领域中筛选检索到的对象中的列表?
答案 0 :(得分:22)
Realm没有深度过滤视图的任何概念,因此您不能使Results<Canteen>
将相关对象中包含的List
限制为素食。
您可以做几件类似的事情。您可以添加反关系属性,然后查询Meal
对象:
class Canteen: Object {
dynamic var name: String?
let lines = List<Line>()
}
class Line: Object {
dynamic var name: String?
let meals = List<Meal>()
let canteens = LinkingObjects(fromType: Canteen.self, property: "lines")
}
class Meal: Object {
dynamic var name: String?
dynamic var vegan: Bool = false
let lines = LinkingObjects(fromType: Line.self, property: "meals")
}
let meals = realm.objects(Meal).filter("vegan = true AND ANY lines.canteens.name = %@", selectedCanteenType.rawValue)
(或者更确切地说,你可以在Realm 0.102.1出局时出现;目前崩溃了。)
如果您只是需要重复进餐而需要从食堂下来,您可以这样做:
let canteens = realm.objects(Canteen).filter("name = %@ AND ANY lines.meals.vegan = true", selectedCanteenType.rawValue)
for canteen in canteens {
for line in canteen.lines.filter("ANY meals.vegan = true") {
for meal in line.meals.filter("vegan = true") {
// do something with your vegan meal
}
}
}
遗憾的是,由于需要为每个级别的引用重复过滤器,因此存在一些重复。
答案 1 :(得分:1)
试试这个:
let predicate = NSPredicate(format: "name == %@", "")
var canteens: [Canteen] = realm.objects(Canteen).filter(predicate).map { can in
// Iterate through all the Canteens
let lines: [Line] = can.lines.map { (line: Line) in
// Iterate through all the lines in each canteene
// Filter all the Meals that are NOT vegan
let meals = line.meals.filter { $0.vegan == true }
line.meals = List<Meal>(meals)
return line
}
can.lines = List<Line>(lines)
return can
}
答案 2 :(得分:0)
Realm允许它使用函数作为过滤参数。所以这是我目前正在使用的解决方案。
两个过滤功能:
func vegetarianFilter(_ meal: Meal) -> Bool {
if showVegetarianOnly {
if(meal.veg || meal.vegan){
return true
}
return false
}
return true
}
func filterEmptyLines(_ line: Line) -> Bool {
if(line.meals.filter(vegetarianFilter).count > 0){
return true
}
return false
}
当用户选择showVegetarianOnly = true
时,这些功能会过滤非素食或素食的所有餐点。它还过滤掉所有没有剩饭的线(没有素食或素食)。
TableView最重要的功能:
override func numberOfSections(in tableView: UITableView) -> Int {
return canteenDay?.lines.filter(filterEmptyLines).count ?? 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return canteenDay?.lines.filter(filterEmptyLines)[section].meals.filter(vegetarianFilter).count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let meal = canteenDay!.lines.filter(filterEmptyLines)[indexPath.section].meals.filter(vegetarianFilter)[indexPath.row]
cell.textLabel?.text = meal.meal
return cell
}