玩! Scala:Json reader 和额外的 class 字段

Play! Scala: Json reader and additional class field

我正在使用 Play! Scala 2.2,我正在阅读 json 如下,效果很好:

case class YoutubeTrack(//artistId: String,
                          videoId: String,
                          title: String,
                          thumbnail: Option[String] )
val youtubeTrackReads: Reads[YoutubeTrack] = (
      (__ \ "id" \ "videoId").read[String] and
        (__ \ "snippet" \ "title").read[String] and
        (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
      )(YoutubeTrack)

现在我想在我的 YoutubeTrack class 中添加一个字段(在 class 声明中注释的 artistId)。 这个字段是我在别处定义的变量。

如何在阅读 json 的同时将此字段添加到我的 YoutubeTrack,即我想做类似的事情:

val youtubeTrackReads: Reads[YoutubeTrack] = (
      (__ \ "id" \ "videoId").read[String] and
        (__ \ "snippet" \ "title").read[String] and
        (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
      )((artistId, videoId, title, url) => YoutubeTrack(artistId, videoId, title, url))

给定函数

def toArtistId(
    videoId: String,
    title: String,
    thumbnail: Option[String]): String = ...
  1. 您甚至可以在不更改 reader

    的情况下添加您的艺术家 ID
    case class YoutubeTrack(
        videoId: String,
        title: String,
        thumbnail: Option[String]) {
        val artistId = toArtistId(videoId, title, thumbnail)
    }
    
  2. 或者像这样改变你的reader

    (
        (__ \ "id" \ "videoId").read[String] and 
        (__ \ "snippet" \ "title").read[String] and
        (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
    )((videoId, title, thumbnail) => 
         YoutubeTrack(toArtistId(videoId, title, thumbnail), videoId, title, thumbnail)
    )
    
  3. 甚至这样

    def artistReader(artistId: String): Reads[YoutubeTrack] = {
        (
            (__ \ "id" \ "videoId").read[String] and
            (__ \ "snippet" \ "title").read[String] and
            (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
        )((videoId, title, thumbnail) => 
            YoutubeTrack(artistId, videoId, title, thumbnail))
    }
    
    artistReader("A")
    
case class YoutubeTrackTemp(
  videoId: String,
  title: String,
  thumbnail: Option[ String ]
)

val youtubeTrackReads: Reads[ YoutubeTrack ] = (
  ( __ \ "id" \ "videoId" ).read[ String ] and
    ( __ \ "snippet" \ "title" ).read[ String ] and
    ( __ \ "snippet" \ "thumbnails" \ "default" \ "url" ).readNullable[ String ]
  )( YoutubeTrackTemp )

case class YoutubeTrack(
  artistId: String,
  videoId: String,
  title: String,
  thumbnail: Option[ String ]
)

object YoutubeTrack {
  def apply( yt: YoutubeTrackTemp ): YoutubeTrack = {
    val artistId = getArtistIdSomehow()
    YoutubeTrack( artistId, yt.videoId, yt.title, yt.thumbnail )
  } 
}

val youtubeTrack = YoutubeTrack( myjson.as[ YoutubeTrackTemp ] )