2017-06-17 74 views
1

我有以下型號:如何基於多個列表映射任意元素?

case class Car(brand: String, year: Int, model: String, ownerId: String) 
case class Person(firstName: String, lastName: String, id: String) 
case class House(address: String, size: Int, ownerId: String) 
case class Info(id: String, lastName: String, carModel: String, address: String) 

我想基於以下列出了編譯List[Info]

val personL: List[Person] = List(Person("John", "Doe", "1"), Person("Jane", "Doe", "2")) 
val carL: List[Car] = List(Car("Mercedes", 1999, "G", "1"), Car("Tesla", 2016, "S", "4"), Car("VW", 2015, "Golf", "2")) 
val houseL: List[House] = List(House("Str. 1", 1000, "2"), House("Bvl. 3", 150, "8")) 

的信息應根據personL收集,例如:

val info = personL.map { p => 
     val car = carL.find(_.ownerId.equals(p.id)) 
     val house = houseL.find(_.ownerId.equals(p.id)) 
     val carModel = car.map(_.model) 
     val address = house.map(_.address) 
     Info(p.id, p.lastName, carModel.getOrElse(""), address.getOrElse("")) 
     } 

結果:

info: List[Info] = List(Info(1,Doe,G,), Info(2,Doe,Golf,Str. 1)) 

現在我想知道是否有一個表達式比我的地圖結構更加簡潔,它完全解決了我的問題。

回答

2

這裏是一個選項,通過建立從OWNERID地圖建模和先解決,然後擡頭看信息,同時通過人列表循環:

val carMap = carL.map(car => car.ownerId -> car.model).toMap 
// carMap: scala.collection.immutable.Map[String,String] = Map(1 -> G, 4 -> S, 2 -> Golf) 

val addrMap = houseL.map(house => house.ownerId -> house.address).toMap 
// addrMap: scala.collection.immutable.Map[String,String] = Map(2 -> Str. 1, 8 -> Bvl. 3) 

personL.map(p => Info(p.id, p.lastName, carMap.getOrElse(p.id, ""), addrMap.getOrElse(p.id, ""))) 
// res3: List[Info] = List(Info(1,Doe,G,), Info(2,Doe,Golf,Str. 1)) 
0

我想說的內涵使用。如果您需要的是結果是在這種情況下,將類似於left join那麼對於理解還是醜:

for { 
    person <- persons 
    model <- cars.find(_.ownerId == person.id).map(_.model).orElse(Some("")).toList 
    address <- houses.find(_.ownerId == person.id).map(_.address).orElse(Some("")).toList 
} yield Info(person.id, person.lastName, model, address) 

請注意,您可以刪除在這一特殊情況下,這兩個選項發電機.toList呼叫出現在集合後發電機。

如果你可以犧牲的默認模型/地址值那麼它看起來很簡單:

for { 
    person <- persons 
    car <- cars if car.ownerId == person.id 
    house <- houses if house.ownerId == person.id 
} yield Info(person.id, person.lastName, car.model, car.address) 

希望有所幫助。

0

可能將hashmaps中的單個列表轉換爲map函數,並通過鍵查找而不是遍歷所有這些列表中的每個元素都可能有幫助?

相關問題