Scala 如果列表不为空,则返回尾部或返回空列表
从电子邮件列表中,我必须得到两个值:Scala 如果列表不为空,则返回尾部或返回空列表,scala,Scala,从电子邮件列表中,我必须得到两个值: 列表标题的选项 其他人的名单 用scala编写代码的惯用方法是什么?到目前为止,我已经: val primaryEmail = emails.headOption val conf = Map[String, Any]( "email" -> primaryEmail, "additionalEmails" -> primaryEmail.map(_ => emails.tail).getOrElse(List())
- 列表标题的选项
- 其他人的名单
val primaryEmail = emails.headOption
val conf = Map[String, Any](
"email" -> primaryEmail,
"additionalEmails" ->
primaryEmail.map(_ => emails.tail).getOrElse(List())
)
编辑:至于为什么会有
Any
:我们使用GSON进行json序列化,并在内部将所有集合转换为java集合,并将它们传递给java集合,java集合以java.lang.Object作为参数,因此Any
非常适合我们。我可能只删除第一个元素(如果您确定第一个元素始终是主电子邮件)。例如:
val conf = Map[String, Any](
"email" -> emails.headOption,
"additionalEmails" -> emails.drop(1)
)
如果主电子邮件不在列表中(列表为空),则不会出现例外情况。学习scalaz。一次呼叫即可获得所有这些:
val (primary, rest) = list <^> (nel => some(nel.head) -> nel.tail)
val conf = Map("email" -> primary, "additionalEmails" -> rest)
如果非空
scala> val (primary, rest) = list <^> (nel => some(nel.head) -> nel.tail)
primary: Option[Int] = Some(1)
rest: List[Int] = List(2, 3)
scala>val(primary,rest)=list(nel=>some(nel.head)->nel.tail)
主:选项[Int]=Some(1)
rest:List[Int]=List(2,3)
如果为空:
scala> val list = List.empty[Int]
list: List[Int] = List()
scala> val (primary, rest) = list <^> (nel => some(nel.head) -> nel.tail)
primary: Option[Int] = None
rest: List[Int] = List()
scala>val list=list.empty[Int]
list:list[Int]=list()
scala>val(primary,rest)=list(nel=>some(nel.head)->nel.tail)
主:选项[Int]=无
rest:List[Int]=List()
这是怎么回事?
调用显示:如果此列表为空,则将return type函数定义的类型的零返回到右侧。如果列表为非空,则对其应用该函数
值nel
是一个NonEmptyList
,我可以安全地调用head
和tail
,而不用担心它们会抛出异常。我的函数返回一个(选项[a],列表[a])
当然,对于任何A
我建议,这个值的零就是(None,Nil)
(("email", "additionalEmail") zip emails.splitAt(1)).toMap
这样一来,第一封电子邮件就留在列表中了
不是一个选项
,而是一个Map[String,Product]
无论如何都不会对您有多大好处,是吗?Map[String,Any]?您不妨编写PHP…;-)
还有一种方法:
scala> def build( emails:Seq[String] ):Map[String,Any] =
emails.headOption.map(
(primary) => Map( "primary" -> Some(primary), "other" -> emails.tail )
).getOrElse( Map( "primary" -> None, "other" -> Nil ) )
build: (emails: Seq[String])Map[String,Any]
scala> build(Nil)
res2: Map[String,Any] = Map(primary -> None, other -> List())
scala> build( List("fred"))
res3: Map[String,Any] = Map(primary -> Some(fred), other -> List())
真的-我不喜欢整个方法-我会这样做:
case class EmailTo( primary:String, other:Seq[String] );
object EmailTo {
def apply( addrs:Seq[String] ):Option[EmailTo] =
addrs.headOption.map( (primary) => EmailTo( primary, addrs.tail ) )
}
对于序列,您可以对其进行模式匹配,以获得头部和其他部分
val lst1 = Seq("primary", "secondary", "other");
// ...
lst1 match {
case Seq(primary, rest @ _*) => println(primary + "/" + rest);
case _ => println("Error: list empty.");
}
如果您使用Scala的列表
s,它甚至更好:
val lst2 = List("primary", "secondary", "other");
// ...
lst2 match {
case primary :: rest => println(primary + "/" + rest);
case Nil => println("Error: list empty.");
}
另见和
就像鲁本一样,我强烈建议你不要使用Map[String,Any]
或类似的结构。你把Scala的类型系统给你的东西都扔掉了。很容易得到很难追踪的错误。也许可以把它作为另一个问题来问——描述一下为什么现在使用Map[String,Any]
,并询问如何改进它。这仍然是一件事吗?接线员似乎已经不存在了。
val lst2 = List("primary", "secondary", "other");
// ...
lst2 match {
case primary :: rest => println(primary + "/" + rest);
case Nil => println("Error: list empty.");
}