首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我能在Scala中映射列表并同时展开它吗?

我能在Scala中映射列表并同时展开它吗?
EN

Stack Overflow用户
提问于 2017-11-22 23:19:04
回答 3查看 245关注 0票数 2

我有一个像这样的Tuple-2的列表:

代码语言:javascript
复制
val stuff = List( ("!thing","value"), ("otherthing","value") )

我想传递这个列表,并从如下内容创建对象:

代码语言:javascript
复制
val processed = stuff.map{ case (label, value) => 
  if(label.startsWith("!"))
    BigThing(label.tail,value) // extends trait Thing
  else
    LittleThing(label,value) . // extends trait Thing
}

到目前一切尚好。现在的问题..。

当我在这些元组上映射时,如果标签以"!“开头,我还想创建一个Bonus(label.tail)对象(也扩展了特性),并将这个对象添加到结果列表中。这意味着,n项的输入列表可能会产生一个>n项的列表。对此,最简化的功能解决方案是什么?

最终想要的输出是一个扩展的事物列表。因此,从理论上讲,上面的例子会产生(顺序不重要):

代码语言:javascript
复制
List( BigThing("thing","value"), Bonus("thing"), LittleThing("otherthing","value") ) 
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-22 23:34:33

为此,我将使用flatMap

代码语言:javascript
复制
val processed = stuff.flatMap { case (label, value) =>
  if (label.startsWith("!"))
    List(BigThing(label.tail, value), Bonus(label.tail))
  else
    List(LittleThing(label, value))
}

结果:

代码语言:javascript
复制
List(BigThing(thing,value), Bonus(thing), LittleThing(otherthing,value))
票数 3
EN

Stack Overflow用户

发布于 2017-11-22 23:35:56

foldLeft怎么样?

代码语言:javascript
复制
val processed = stuff.foldLeft(List.empty[Thing]) { case (list, (label, value)) =>
  if (label.startsWith("!")) {
    list ++ (BigThing(label.tail, value) :: Bonus(label.tail) :: Nil)
  } else list :+ LittleThing(label,value)
}
票数 2
EN

Stack Overflow用户

发布于 2017-11-23 07:54:16

因为这个问题已经有了答案,但是如果我们注意到返回类型是List[Product with Serializable],因为您试图创建一个包含不相关案例类的列表,并且它没有进入最佳实践。

Ex:

代码语言:javascript
复制
scala> val processed = stuff.flatMap { case (label, value) =>
     |   if (label.startsWith("!"))
     |     List(BigThing(label.tail, value), Bonus(label.tail))
     |   else
     |     List(LittleThing(label, value))
     | }
processed: List[Product with Serializable] = List(BigThing(thing,value), Bonus(thing), LittleThing(otherthing,value))

我们可以通过显式提供返回类型来删除它。因为我们返回不同案例类的列表,所以我们可以使用Lis[Any]

Ex:

代码语言:javascript
复制
scala> trait Thing extends Product with Serializable
defined trait Thing

scala> case class BigThing(id: String, value: String) extends Thing
defined class BigThing

scala> case class Bonus(id: String) extends Thing
defined class Bonus

scala> case class LittleThing(id: String, value: String) extends Thing
defined class LittleThing

scala> val stuff = List( ("!thing","value"), ("otherthing","value") )
stuff: List[(String, String)] = List((!thing,value), (otherthing,value))

scala>  val result = stuff.flatMap { case (label, value) =>
     |         label match {
     |           case lable if label.startsWith("!") => List(BigThing(label.tail, value), Bonus(label.tail))
     |           case _ => List(LittleThing(label, value))
     |         }
     |       }
result: List[Thing] = List(BigThing(thing,value), Bonus(thing), LittleThing(otherthing,value))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47445317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档