Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如果列表不为空,则返回尾部或返回空列表_Scala - Fatal编程技术网

Scala 如果列表不为空,则返回尾部或返回空列表

Scala 如果列表不为空,则返回尾部或返回空列表,scala,Scala,从电子邮件列表中,我必须得到两个值: 列表标题的选项 其他人的名单 用scala编写代码的惯用方法是什么?到目前为止,我已经: val primaryEmail = emails.headOption val conf = Map[String, Any]( "email" -> primaryEmail, "additionalEmails" -> primaryEmail.map(_ => emails.tail).getOrElse(List())

从电子邮件列表中,我必须得到两个值:

  • 列表标题的选项
  • 其他人的名单
用scala编写代码的惯用方法是什么?到目前为止,我已经:

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.");
}