将选项[A]预先添加到选项[列表[A]]的惯用法

时间:2013-05-26 08:15:49

标签: scala

我有:ox: Option[A]oxs: Option[List[A]]

我想:

  • 如果两者都存在,则返回ox.get :: oxs.get

  • 如果List(ox.get)存在且ox没有,则返回oxs

  • 如果oxs.get存在且oxs没有,则返回ox

  • 如果两者都是List(),则返回None

我可以使用ifmatches实现这一目标。我只是想知道是否有任何优雅的惯用方式呢?

编辑:我已经测试过:List(ox.map(List(_)), oxs).flatten.flatten它似乎适用于所有四种情况,但它看起来仍然有点难以理解。

3 个答案:

答案 0 :(得分:7)

尝试,

ox.toList ++ oxs.toList.flatten

如果你不介意结果是Iterable[Int]而不是List[Int],你可以删除最初的toList

ox ++ oxs.toList.flatten

答案 1 :(得分:4)

val oa: Option[A] = ???
val oas: Option[List[A]] = ???

val result = oa ++: oas.getOrElse( Nil ) // O(1).
val result2 = oa ++: oas.flatten // 2.9.x only. same result, less performance (O(N)).
val result3 = oa ++: oas.toList.flatten // 2.10.x. O(N).

Flatten在List中创建新的result2,而result重复使用初始列表:

val oa = Some(1)
val as = List(2,3)
val oas = Option(as)

val result = oa ++: oas.getOrElse( Nil )
// List(1, 2, 3)

val result2 = oa ++: oas.flatten
// List(1, 2, 3)

result.tail eq as // true - same object

result2.tail eq as // false - new object

答案 2 :(得分:2)

您还可以使用for comprehension:

for (x <- ox; xs <- oxs) yield x :: xs

这是一种更好的写作方式

ox.flatMap(x => oxs.map(xs => x :: xs))