Scala 将序列中的某些项映射为“无”时进行类型检查

Scala 将序列中的某些项映射为“无”时进行类型检查,scala,sequences,Scala,Sequences,以下代码遍历一些节点列表,并为一些节点创建段落或标题对象: abstract class Element case class Paragraph(node: Node) extends Element case class Heading(mainNode: Node, textNode: Node) extends Element val elements = parent.child.map(n => if (n.label ==

以下代码遍历一些节点列表,并为一些节点创建
段落
标题
对象:

  abstract class Element    
  case class Paragraph(node: Node) extends Element
  case class Heading(mainNode: Node, textNode: Node) extends Element

  val elements =
      parent.child.map(n =>
        if (n.label == "p") Paragraph(n)
        else if (n.label.matches("h\d")) Heading(n, n.child.head)
        else None)

接下来,我想去掉
None
元素,并将
元素
传递给需要
Seq[Element]
的函数。但是,
元素
的类型是
Seq[Product with Serializable]
而不是
Seq[Element]
。为什么,以及如何使类型更强大?

使用
collect
而不是
map
仅保留所需的元素:

val elements = parent.child.collect {
    case n if (n.label == "p") => Paragraph(n)
    case n if (n.label.matches("h\d")) => Heading(n, n.child.head))
}
val elements = parent.child.flatMap(n =>
    if (n.label == "p") Some(Paragraph(n))
    else if (n.label.matches("h\d")) Some(Heading(n, n.child.head))
    else None)
传递给
collect
PartialFunction
中未定义的任何内容都将被丢弃


如果您只是想丢弃元素,那么没有理由映射到
None
。如果您出于某种原因想要保留
None
实例,那么其他实例应该映射到
some[Element]
,这样您就有了
Seq[Option[Element]

我同意m-z的观点,
collect
在这里是一个很好的选择。您有时也可以选择使用
flatMap
,并返回
Some
作为所需值,而
None
作为其他值。由于
选项
隐式转换为iterable,因此
flatMap
会将列表平坦化为你想要什么:

val elements = parent.child.collect {
    case n if (n.label == "p") => Paragraph(n)
    case n if (n.label.matches("h\d")) => Heading(n, n.child.head))
}
val elements = parent.child.flatMap(n =>
    if (n.label == "p") Some(Paragraph(n))
    else if (n.label.matches("h\d")) Some(Heading(n, n.child.head))
    else None)

儿童的类型是什么?感谢您的快速回复和详细且非常有用的解释!谢谢您,我会记住的!