2017-04-25 105 views
6

創建從列表,並附有地圖和內部列表,所以我有數據類是這樣的:如何使用科特林

data class Item(val name: String) 
data class Order(val id: Int, val items: List<Item>) 

,我有訂單的列表。

我的問題是,如何使用Kotlin的集合API創建一個包含項目名稱作爲關鍵字和該項目作爲值的訂單列表的地圖?

+0

'associateTo' /'associateBy'是你的朋友。 –

回答

3

既然你有orders: List<Order>,可以先flatMap訂單進入Order對和項目名稱(這樣,如果有一個以上的Item每個Order可發生多次),並通過該項目名稱,然後組這些對使用groupBy,取訂單從對成組:

val result = orders 
     .flatMap { o -> o.items.map { i -> o to i.name } } 
     .groupBy({ (_, name) -> name }, valueTransform = { (o, _) -> o }) 

groupBy參數,{ (_, name) -> name }是分組的鍵選擇函數,它的名稱來自每對,和{ (o, _) -> o }它們收集到時變換項目Ť他列出,它需要從一對訂單。

(runnable demo of this code)

如果你想消除的情況下,同一個Order的多次出現它包含一個Item多次使用distinct如下:.flatMap { o -> o.items.distinct().map { i -> ... } }

+0

謝謝@hotkey!這絕對有效! 現在我想知道如果我們使用associateTo/associateBy @Oliver Charlesworth提到的,我們是否可以有一個更簡單的解決方案。 – lawkai

+0

@lawkai,我對此表示懷疑。 'associate *'函數只能將一系列的項目轉換成一個映射,其中每個條目以某種方式從其中一個項目產生。至少,我沒有看到使用'associate *'的簡單解決方案,它可以做到這一點。 @OliverCharlesworth,請你詳細說明一下嗎? – hotkey

+0

我誤解了OP的意圖 - 「associate *」方法在這裏不太可能有用:/ –