问题是来自class OldCompanyMovie(ocm : List[(company:String, movie:String, actor:String)])
到List[CompanyMovie(company:String, movies: List[Movies(movie:String, actors : List[actor:String])])]
说明:
同一部电影中男主角的名字应该是电影中的男主角,例如class Movies(movie: String, actors: List[actor:String])
与列表演员相同,电影应该是CompanyMovie(company: String, movies : List[movie:Movies]))
这样的公司中的电影列表
总体应为List[CompanyMovie(company:String, Movies(mv : List[movie:String, List[actor:String]]))]
*更新 我已经尝试了整整一天,所以结果差强人意但效果可能不佳
val companies: List[Company] = oldWorldMovieList.map { item =>
val moviesOfeachCompany: List[Option[Pattern]] = oldWorldMovieList.map { oldWML =>
if (item.company == oldWML.company) {
val actorsOfeachMovie: List[Option[String]] = oldWorldMovieList.map { oldWML2 =>
if (item.movie == oldWML2.movie) {
Some(oldWML2.actor)
} else None
}.distinct
Some(Pattern(item.movie, actorsOfeachMovie))
} else None
}.distinct
Company(item.company, moviesOfeachCompany)
}.distinct
val worldMovies: WorldMovies = WorldMovies(companies)
ps。我无法更改源数据的模式。
如果是杰森(Json)就像这样List[String, String, String]
[{"company":"Marvel","movie":"Avengers","actor":"ROBERT DOWNEY JR."},{"company":"Marvel","movie":"Avengers","actor":"CHRIS EVANS"},{"company":"Marvel","movie":"Avengers","actor":"MARK RUFFALO"},{"movie":"Marvel","movie":"Guardian of the galaxy","actor":"KAREN GILLAN"},{"company":"Marvel","movie":"Guardian of the galaxy","actor":"ZOE SALDANA"},{"company":"dc","movie":"Batman","actor":"CHRISTIAN BALE"},{"company":"dc","movie":"Batman","actor":"CHRISTOPHER REEVE"}]
转换后应该是这个
[{"company": "Marvel", "movies" : [{"movie": "Avengers", "actor": ["ROBERT DOWNEY JR.", "CHRIS EVANS", "MARK RUFFALO"]},{"movie": "Guardian of the galaxy", "actor": ["KAREN GILLAN", "ZOE SALDANA"]}]},{"company": "dc","movies" : [{"movie": "Batman", "actor": ["CHRISTOPHER REEVE", "CHRISTIAN BALE"]}]}]
答案 0 :(得分:1)
类似于Norwæ解决方案,但(IMHO)更简单直接。
另外,由于它也使用Iterators
,因此性能可能更高。
final case class OldModel(company: String, movie: String, actor: String)
final case class Company(name: String, movies: List[Movie])
final case class Movie(name: String, actors: List[String])
def toNewModel(oldData: List[OldModel]): List[Company] =
oldData
.groupBy(_.company)
.iterator
.map { case (company, group) =>
val movies =
group
.groupBy(_.movie)
.iterator
.map { case (movie, group) =>
val actors = group.map(_.actor)
Movie(movie, actors)
}.toList
Company(company, movies)
}.toList
答案 1 :(得分:0)
我的尝试。我不确定这是一个好习惯。
val companies: List[Company] = oldWorldMovieList.map { item =>
val moviesOfeachCompany: List[Option[Pattern]] = oldWorldMovieList.map { oldWML =>
if (item.company == oldWML.company) {
val actorsOfeachMovie: List[Option[String]] = oldWorldMovieList.map { oldWML2 =>
if (item.movie == oldWML2.movie) {
Some(oldWML2.actor)
} else None
}.distinct
Some(Pattern(item.movie, actorsOfeachMovie))
} else None
}.distinct
Company(item.company, moviesOfeachCompany)
}.distinct
val worldMovies: WorldMovies = WorldMovies(companies)
答案 2 :(得分:0)
我认为您可以使用groupBy
非常优雅地做到这一点。例如:
case class CompanyMovie(company: String, movies: Seq[Movie])
case class Movie(name: String, actors: Seq[String])
def convert(in: Seq[(String, String, String)]): Seq[CompanyMovie] = {
val byCompany = in.groupBy(_._1)
val byCompanyAndMovie = byCompany.mapValues(_.groupBy(_._2).toSeq)
byCompanyAndMovie.toSeq.map {
case (company, rawMovies) =>
val movies = rawMovies.map {
case (name, t) => Movie(name, t.map(_._3))
}
CompanyMovie(company, movies)
}
}