【问题标题】:how to convert data from duplicated list data to list of group data如何将数据从重复列表数据转换为组数据列表
【发布时间】:2019-10-04 09:02:56
【问题描述】:

问题是来自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"]}]}]

【问题讨论】:

  • 这对大多数程序员来说可能很容易,但它让我感到头晕目眩。
  • List 只有一个通用参数。 List[company:String, movie:String, actor:String] 是什么意思?
  • 向我们展示您的代码,并说明您遇到的问题。
  • "site": "Marvel" 是什么意思?
  • 抱歉 Json 示例失败

标签: java scala list dictionary


【解决方案1】:

我的尝试。我不确定这是一种好习惯。

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】:

    我认为使用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)
      }
    }
    

    【讨论】:

      【解决方案3】:

      类似于 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
      

      【讨论】:

        猜你喜欢
        • 2013-08-08
        • 1970-01-01
        • 2018-10-23
        • 2017-12-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多