我有两个对象。一个名为EstimateItem
,另一个称为Part
(Part
类继承自Realm的Object
类。一个EstimateItem
可以有多个Part
s。
class EstimateItem {
var parts: [Part]?
}
在每个实例中都有EstimateItem
个数组Part
s。
+--------------------------------+---------------------------------+
| EstimateItem | Parts |
+--------------------------------+---------------------------------+
| Line Item 1 - RnR WDH - Twins | Epoxy / Wood for lami |
| (single) | |
| | |
| Line Item 2 - RnR WDH - Twins | Epoxy / Wood for lami |
| (double) | |
| | |
|Line Item 3 - Install sash lock |Epoxy / Wood for lami / Sash lock|
+--------------------------------+---------------------------------+
我需要按特定Part
对它们进行分组。看起来应该是这样的。
我该怎么做?
当部件连接到单个项目时,我无法找到一种方法来执行此操作,因此我尝试将它们全部放在(part: Part, item: EstimateItem)
元组的数组中。< / p>
var groups = [(part: Part, item: EstimateItem)]()
for item in estimateItemsArray {
if let parts = item.parts {
for part in parts {
groups.append((part, item))
}
}
}
// Epoxy - RnR WDH - Twins (single)
// Wood for lami - RnR WDH - Twins (single)
// Epoxy - RnR WDH - Twins (double)
// Wood for lami - RnR WDH - Twins (double)
// Epoxy - RnR WDH - Twins (single)
// Wood for lami - RnR WDH - Twins (single)
// Sash lock, traditional - Install sash lock
然后分组。
但我还是被困住了。此外,我觉得我过度复杂,我想知道是否有更简单,更实际的 Swifty 方法。
答案 0 :(得分:3)
我想要找到更多 swifty 这样做的方法如下:
let parts = Set(estimateItemsArray.flatMap{ $0.parts ?? [] })
let partMap = parts.map { part in
return (part, estimateItemsArray.filter {
$0.parts?.indexOf(part) != nil
}
)
}
partMap
现在包含(Part, [EstimateItem])
形式的元组。唯一的要求是Part
符合Hashable
或相关内容 - 在我的测试中,我只让部分继承自NSObject
。
说明:
Set
以确保唯一性)estimateItemsArray
过滤掉列表中包含当前部分的项目完整的测试数据如下所示
/* the now classes, both include some identifier to distinguish them */
class Item {
var n : String
var parts : [Part]? = [Part]()
init(n:String) {
self.n = n
}
}
class Part : NSObject {
var n : String
init(n:String) {
self.n = n
}
}
/* set up the test data */
let item1 = Item(n: "item 1")
let item2 = Item(n: "item 2")
let item3 = Item(n: "item 3")
let part1 = Part(n: "part 1")
let part2 = Part(n: "part 2")
let part3 = Part(n: "part 3")
item1.parts = [part1, part2]
item2.parts = [part1, part3]
item3.parts = [part1, part2, part3]
var arrItems = [item1, item2, item3]
/* actual logic */
let parts = Set(arrItems.flatMap{ $0.parts ?? [] })
let partMap = parts.map { part in
return (part, arrItems.filter {
$0.parts?.indexOf(part) != nil
}
)
}
/* final output */
partMap.forEach { entry in
print("part \(entry.0.n)")
entry.1.forEach {
print("contains \($0.n)")
}
}
输出:
部分第1部分 包含第1项 包含第2项 包含第3项 第3部分 包含第2项 包含第3项 第2部分 包含第1项 包含第3项
如果您不能像我最初那样继承NSObject
,请让您的班级Part
符合Hashable
,这是集合的要求:
class Part : Hashable {
var n : String
init(n:String) {
self.n = n
}
var hashValue: Int {
return n.hashValue // you basically have to provide some kind of logic based on *your* Part object
}
}
func ==(lhs: Part, rhs: Part) -> Bool {
return lhs.hashValue == rhs.hashValue
}