2015-12-21 45 views
3

我有兩個對象。一個調用EstimateItem,另一個調用PartPart類繼承自Realm的Object類)。一個EstimateItem可以有多個Part s。按數組中的對象分組

class EstimateItem { 
    var parts: [Part]? 
} 

還有的EstimateItem s的在每個實例中不同數目的Part秒的陣列。

+--------------------------------+---------------------------------+ 
|   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對它們進行分組。它應該看起來像這樣。

enter image description here

我該怎麼辦呢?

我想不出辦法做到這一點,而零件是附加個別項目,所以我試圖把它們全部放在一個數組元組(part: Part, item: EstimateItem)

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 

然後對它進行分組。

但我仍然卡住了。此外,我覺得我過於複雜,我想知道是否有一個更容易,更容易做到這一點。

+0

我可以假設你有一個所有零件和物品的數組?像'var parts:[Part]'? – luk2302

+0

@ luk2302沒有單獨的零件陣列。有一系列名爲'estimateItemsArray'的項目。在每一個項目中,都有像你提到的一系列部件。 – Isuru

回答

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 
} 
+0

感謝您的回答。不幸的是有一個障礙。我使用Realm,'Part'類是從Realm自己的Object類繼承而來的,不能修改爲從'NSObject'繼承。我不好意思在我的問題中提及它。所以我得到錯誤**不能在第一行使用類型'([Part])'**'的參數列表調用類型爲'Set <_>'的初始值設定項。有沒有解決方法? – Isuru

+0

這很奇怪,因爲Realm的['Object'](https://realm.io/docs/swift/latest/api/Classes/Object.html)類是從一個名爲'RLMObjectBase'的類繼承而來的,它繼承自'NSObject '本身。但是,我仍然得到了這個錯誤。 – Isuru

+0

@Isuru我是聖誕節購物,現在就來看看吧。 – luk2302