我有一个Option[Seq[String]]
,试图找到一种向该集合添加Option[String]
的最佳方法,从而再次产生一个Option[Seq[String]]
。如果集合为None
,但要添加的值为Some[String]
,则结果应为具有该单个值的Option[Seq[String]]
。
我想出了两种写方法,基本上可以归结为相同的方法。我觉得必须有更好的方法来做到这一点。有什么建议么?
val messages: Option[Seq[String]] = Some(Seq("item"))
val message: Option[String] = Some("item 2")
val opt1: Option[Seq[String]] = message match {
case Some(message) => Some(messages.map(_ :+ message).getOrElse(Seq(message)))
case None => messages
}
val opt2: Option[Seq[String]] = message
.map(msg => Some(messages.map(_ :+ msg).getOrElse(Seq(msg))))
.getOrElse(messages)
println(opt1) // Some(List(item, item 2))
println(opt2) // Some(List(item, item 2))
答案 0 :(得分:3)
messages
可用时。将message
转换为Seq并将其添加到现有消息中。
否则将message
转换为Option[Seq[String]]
messages.map(msgs => msgs ++ message.toSeq)
.orElse(message.map(x => Seq(x)))
清晰的语法
messages.map(_ ++ message.toSeq) orElse message.map(Seq(_))
scala> :paste
// Entering paste mode (ctrl-D to finish)
def addOption[T](messages: Option[Seq[T]], message: Option[T]): Option[Seq[T]] =
messages.map(msgs => msgs ++ message.toSeq)
.orElse(message.map(Seq(_)))
// Exiting paste mode, now interpreting.
addOption: [T](messages: Option[Seq[T]], message: Option[T])Option[Seq[T]]
scala> addOption(Some(Seq(1)), Some(2))
res4: Option[Seq[Int]] = Some(List(1, 2))
scala> addOption(Some(Seq(1)), Some(3))
res5: Option[Seq[Int]] = Some(List(1, 3))
scala> addOption(Some(Seq(1)), None)
res6: Option[Seq[Int]] = Some(List(1))
scala> addOption(None, None)
res7: Option[Seq[Nothing]] = None
scala> addOption(None, Some(1))
res8: Option[Seq[Int]] = Some(List(1))
scala> addOption(None, Some(2))
res9: Option[Seq[Int]] = Some(List(2))
答案 1 :(得分:1)
这里是另一个:
def push[T](message: Option[T], messages: Option[Seq[T]]): Option[Seq[T]] =
message.map(s => messages.getOrElse(Nil) :+ s).orElse(messages)
产生:
push(Some("!"), Some(Seq("hello", "world"))) // Some(List(hello, world, !))
push(None, Some(List("hello", "world"))) // Some(List(hello, world))
push(Some("!"), None) // Some(List(!))
push(None, None) // None
答案 2 :(得分:0)
这是使用fold的一种方法:
def addOptMsg[T](msgs: Option[Seq[T]], msg: Option[T]): Option[Seq[T]] =
msgs.fold( msg.map(Seq(_)) )( s => Option(s ++ msg.toSeq) )
测试方法:
val messages: Option[Seq[String]] = Some(Seq("item1", "item2"))
val message: Option[String] = Some("item3")
val messages0: Option[Seq[String]] = None
val message0: Option[String] = None
addOptMsg(messages, message)
// res1: Option[Seq[String]] = Some(List(item1, item2, item3))
addOptMsg(messages, message0)
// res2: Option[Seq[String]] = Some(List(item1, item2))
addOptMsg(messages0, message)
// res3: Option[Seq[String]] = Some(List(item3))
addOptMsg(messages0, message0)
// res4: Option[Seq[String]] = None
答案 3 :(得分:0)
使用fold
opt2变为:
val opt2: Option[Seq[String]] =
message.fold(messages)(msg => Some(messages.fold(Seq(msg))(_ :+ msg)))
[由Intellij自动转换:)]