[英]Scala immutable lists adding a 'Unit' element
我是scala的初学者,我正在寻找最好/惯用的方式去做我打算在这里做的事情。
这就是我想要做的
def someMethod(obj:MyObj):List[String] = {
List[String]() +:
{if (somecondition is satisfied) .. " element"} +:
{ if (another condition) .. " something else " }
}
也就是说,该方法检查输入参数对象的某些属性,并将元素添加到List(即要返回)。 如果没有满足任何条件,则应返回空列表。
并且2.请告诉我正确的方法来做Scala。 如果我在一系列条件上进行迭代,我可以使用理解。
我宁愿使用一元或空列表,而不是过滤单位:
def someMethod(obj:MyObj): List[String] = {
Nil ++
( if (somecondition is satisfied) List(" element") else Nil ) ++
( if (another condition) .. List(" something else ") else Nil ) ++
}
编辑:关于下面的评论,如果你发现上面的代码太冗长和难以维护,你仍然可以创建一个辅助函数:
def optElem[T]( condition: Boolean)( value: => T ): Option[T] = if ( condition ) Option( value ) else None
def someMethod(obj:MyObj): List[String] = {
Nil ++
optElem (somecondition is satisfied)( " element") ++
optElem (another condition)(" something else " )
}
if
- else
是Scala中的表达式。 你写的内容变成了:
List[String]() +:
{if (somecondition is satisfied) {" element"; () } else () }+:
{ if (another condition) { " something else "; () } else () }
如您所见,常见的分支类型是Unit
。
整个表达式的类型是List[Any]
因为这是String
和Unit
的常见超类型。
一些方法来实现你想要的:
// #1. Ugly.
def someMethod(obj:MyObj):List[String] = {
val xs = List[String]()
val xs1 = if (somecondition is satisfied) xs :+ " element" else xs
val xs2 = if (another condition) xs1 :+ " something else" else xs1
xs2
}
// #2. Better, but uses mutable builder.
def someMethod(obj:MyObj):List[String] = {
val b = List.newBuilder[String]
if (somecondition is satisfied) b += " element"
if (another condition) b += " something else"
b.result
}
// #3. Best way IMO, but computationally expensive.
def someMethod(obj:MyObj):List[String] = {
List[String]() ++
Option("element").filter(some condition) ++ // for more correct semantics
// use LazyOption from Scalaz.
Option("something else").filter(another condition)
}
你可以这样写:
def someMethod(obj:MyObj):List[String] = {
List(
if (somecondition is satisfied) " element",
if (another condition) " something else "
) collect{ case x: String => x }
}
假设所有条件都失败了:您将首先按List(Unit,Unit)
结束List(Unit,Unit)
然后按类型过滤 。 单位不满足收集内的类型条件,因此结果将为空列表
好处是,与filter
方法不同, collect
选择尽可能紧密的类型(因此你将获得字符串序列 - 这将来自收集中的函数)。
另一种可能性是用flatten
替换.collect { ... }
,但你会丢失类型信息。
另一种观点是构建一个选项列表,然后展平列表。
def f(obj: MyObj): List[String] = {
List(if (cond1(obj)) Some("element") else None,
if (cond2(obj)) Some("something else") else None).flatten
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.