【问题标题】:Scala: map function not returning desired resultScala:映射函数未返回所需结果
【发布时间】:2017-10-26 10:30:49
【问题描述】:

我正在编写一个必须返回 List[TaskSchedule] 的 scala 函数。

如果我这样做,它会返回所需的类型:

val taskSchedules = orders.flatMap { order => createSchedules(order, order.prod.tasks) }

问题是我想运行createSchedules n 次,所以我这样做了:

val taskSchedules = orders.map { order => (1 to order.quantity) foreach ( _ => createSchedules(order, order.prod.tasks) )}

但是这样一来,taskSchedules 是来自类型List[Unit]

我在这里做错了什么?

【问题讨论】:

  • 你在返回 void(或 Unit)的地图内做 foreach

标签: scala list foreach


【解决方案1】:

foreach 返回 Unit,因此您将订单从 List[OrderClass] 映射到 List[Unit]。

我不是 100% 确定您的目标是什么,但是,假设您的目标是最终拥有相同的类型(只需从每个 createSchedules 创建多个结果,并且 createSchedules 也返回一个列表),那么您会想要这样做:

val taskSchedules = orders.flatMap { order => (1 to order.quantity) flatMap ( _ => createSchedules(order, order.prod.tasks) )}

【讨论】:

  • 再告诉我一件事。有没有办法获取实例的索引,以便我可以将它作为参数发送到 createSchedules 函数?
  • 实例的索引是什么意思?如果您指的是订单实例,那么您可以使用 zipwithIndex 或简单地遍历 orders.indices 并通过 orders(i) 获取订单。如果您指的是订单数量的索引,那么只需命名它而不是使用 _
  • @JCosta 你需要(1 to order.quantity).map(index => createSchedule(index, ...))。答案中的_ 只是一个占位符,用你想要的任何名称替换它。
  • prayagupd 帮助了我。谢谢你们俩。
【解决方案2】:

由于您在.map 中使用.foreach,因此最终响应将是List[Unit],因为foreach 是无返回操作。例如,参见List#foreach

  // Overridden with an implementation identical to the inherited one (at this time)
  // solely so it can be finalized and thus inlinable.
  @inline final override def foreach[U](f: A => U) {
    var these = this
    while (!these.isEmpty) {
      f(these.head)
      these = these.tail
    }
  }

所以,最好在响应很重要时使用.map,而不仅仅是使用foreach 就可以了。

例子,

输入

scala> val orders = List(("orderA", 1), ("orderB", 2))
orders: List[(String, Int)] = List((orderA,1), (orderB,2))

返回响应的函数

scala> def scheduleOrder(order: String) = s"$order will be shipped"
scheduleOrder: (order: String)String

处理输入 n 次并存储结果

scala> orders.map( order => Range.inclusive(1, order._2).map(counter => scheduleOrder(counter +"-" +order._1))).flatten
res9: List[String] = List(1-orderA will be shipped, 1-orderB will be shipped, 2-orderB will be shipped)

【讨论】:

    【解决方案3】:

    使用 for 推导式是在 Scala 中实现此目的的惯用方式。

    val taskSchedules = for {
      order <- orders 
      _ <- 1 to order.quantity 
    } yield  createSchedules(order, order.prod.tasks) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-02
      • 1970-01-01
      相关资源
      最近更新 更多