使用另一个数组的Swift Array of Realm对象过滤器

时间:2018-03-30 06:24:42

标签: arrays swift realm

我遇到过滤领域对象的问题

这是我的领域模型对象

class OutletDTO: Object, Mappable {
    var tags = List<OutletTag>()
}
class OutletTag: Object, Mappable {
    @objc dynamic var tagName: String?
}

JSON将返回Outlets列表,每个插座都有几个标签

"tags": [
{
    "tagName": "A"
},
{
    "tagName": "B"
},
{
    "tagName": "C"
},
{
    "tagName": "D"
}
]

所以我想根据插座的标签实现过滤功能

我有几个按钮会将过滤字符串添加到[String]。 我打算做的是,获取我的领域出口对象,然后检查标签是否包含[FilterString]

我目前的代码是

self.storeList = Array(realmOutletList).filter({ Array($0.tags).map({$0.tagName!}).sorted().joined().contains(self.filterArray.sorted().joined()) })

然而,这段代码并没有给我我想要的东西。

例如

Outlet A, has tag : A, B, C 
Outlet B, has tag : B, C, D
Filter Array: A, D
Result: Outlet A and B // What i want is the result empty because no outlet has both A and D

另一个例子

Outlet A : A, B, C
Outlet B : A
Filter String: A, B
Expected Result: Outlet A // because A, B matches Outlet A. 
//Outlet B must be removed because there is no "B" inside the outlet B
Filter String: A 
Expected Result: Outlet A and Outlet B because they both have "A" inside

有人可以指导我吗?如果有另一种方法可以实现这一点也受到欢迎,因为我想不出其他方法来实现这个功能。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用Set的isSubSet方法。

  

public func isSubset(of other:Set) - &gt;布尔

我可以用你的例子解释这个

  • 获取

获取您的领域数据

    let tagA = OutletTag(); tagA.tagName = "A"
    let tagB = OutletTag(); tagB.tagName = "B"
    let tagC = OutletTag(); tagC.tagName = "C"
    let tagD = OutletTag(); tagD.tagName = "D"

    let outlet1 = OutletDTO(); outlet1.tags.append(objectsIn: [tagA,tagB,tagC])
    let outlet2 = OutletDTO(); outlet2.tags.append(objectsIn: [tagA,tagC])


    do {
        try self.realm.write {
            self.realm.add([outlet1,outlet2])
        }
    } catch  {
        print("Error saving category \(error)")
    }

    let outlets = self.realm.objects(OutletDTO.self)

    let filterTag1 = OutletTag(); filterTag1.tagName = "A"
    let filterTag2 = OutletTag(); filterTag2.tagName = "B"

    let filterTags = [filterTag1,
                      filterTag2]
  • 转换

将您的filterTags表单List转换为Set of String。

    let filterTagStrings = [filterTag1,
                      filterTag2].map({ (tag) -> String in
                        return tag.tagName ?? ""
                      })
    let setFilterTagStrings = Set(filterTagStrings)
  • 过滤

带标签的过滤列表

    var filteredOutlets = [OutletDTO]()
    for outlet in outlets {

        let outletTagStrings:[String] = outlet.tags.map({ (tag) -> String in
            return tag.tagName ?? ""
        })
        let setOutletTagStrings = Set(outletTagStrings)

        if setFilterTagStrings.isSubset(of:setOutletTagStrings) {
            filteredOutlets.append(outlet)
        }
    }

    //Out put
    print(filteredOutlets)