如何使用`flatMap`和`map`填充Play框架+ Scala上的`list`?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用`flatMap`和`map`填充Play框架+ Scala上的`list`?相关的知识,希望对你有一定的参考价值。

我正在努力使用flatMap并使用Play framework + Scala进行映射。这个方法有很多其他问题,但我每次尝试一次。我无法弄清楚如何实现的第一件事是如何在嵌套的flatMap中填充Seq并映射并返回Json输出。这是我的方法:

  def getRacks(at: String) = Action.async { implicit request: Request[AnyContent] =>

    var rackSeq: Seq[Rack] = Seq.empty
    var gpuSeq: Seq[Gpu] = Seq.empty

    rackRepository.get(Util.toTime(at)).flatMap { resultRack: Seq[RackRow] =>
      resultRack.map { r: RackRow =>
        gpuRepository.getByRack(r.id).map { result: Seq[GpuRow] =>
          result.map { gpuRow: GpuRow =>
            gpuSeq = gpuSeq :+ Gpu(gpuRow.id, gpuRow.rackId, gpuRow.produced, Util.toDate(gpuRow.installedAt))
            println(gpuRow)
          }
        }
        val rack = Rack(r.id, r.produced, Util.toDate(r.currentHour), gpuSeq)
        rackSeq = rackSeq :+ rack
      }
      println("rackSeq: " + rackSeq)
      Future.successful(Ok(Json.toJson(rackSeq)).as(JSON))
    }.recover {
      case pe: ParseException => BadRequest(Json.toJson("Error on parse String to time."))
      case e: Exception => BadRequest(Json.toJson("Error to get racks."))
      case _ => BadRequest(Json.toJson("Unknow error to get racks."))
    }
  }

我期待rackSeq将充满GpuRow。但我的输出是这样的:

rackSeq: List(Rack(rack-1,0.2,2018-01-23T14:15:00.79Z,List()))
GpuRow(rack-1-gpu-0,rack-1,0.2,1515867048515)

如何评估两个列表到输出?

答案

而不是改变变量,保持在Future的上下文中并执行转换,直到达到所需的结果。假设以下类型......

rackRepository.get(Util.toTime(at)) // Future[Seq[RackRow]]
gpuRepository.getByRack(r.id)       // Future[Seq[GpuRow]]

......你可以这样做:

def gpuRowToGpu(gpuRow: GpuRow): Gpu = {
  Gpu(gpuRow.id, gpuRow.rackId, gpuRow.produced, Util.toDate(gpuRow.installedAt))
}

def getRacks(at: String) = Action.async { implicit request: Request[AnyContent] =>

  rackRepository.get(Util.toTime(at)).flatMap { resultRack: Seq[RackRow] =>
    val seqFutRack: Seq[Future[Rack]] = resultRack.map { r: RackRow =>
      gpuRepository.getByRack(r.id).map { result: Seq[GpuRow] =>
        val gpus = result.map(gpuRowToGpu) // Seq[Gpu]
        Rack(r.id, r.produced, Util.toDate(r.currentHour), gpus)
      } // Future[Rack]
    }
    val futSeqRack: Future[Seq[Rack]] = Future.sequence(seqFutRack)
    futSeqRack.map(racks => Ok(Json.toJson(racks)).as(JSON))
  }.recover {
    ...
  }
}

以上是关于如何使用`flatMap`和`map`填充Play框架+ Scala上的`list`?的主要内容,如果未能解决你的问题,请参考以下文章

对flatMap / Map转换的理解感到困惑

map,flatMap和flatMapLatest的区别

FlatMap vs Filter,Map Java [重复]

Swift - 使用 map/reduce/flatmap 将数组字典减少为相同类型的单个数组

在 Scala Akka 期货中,map 和 flatMap 有啥区别?

理解Swift中map 和 flatMap对集合的作用