2017-06-17 75 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函数,并通过键查找而不是遍历所有这些列表中的每个元素都可能有帮助?

相关问题