以下代码遍历某些节点列表,并为某些节点创建Paragraph
或Heading
个对象:
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
元素并将elements
传递给需要Seq[Element]
的某个函数。但是,elements
的类型为Seq[Product with Serializable]
而不是Seq[Element]
。为什么,以及如何使类型更强?
答案 0 :(得分:4)
使用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))
}
在您传递给PartialFunction
的{{1}}中未定义的任何内容都将被丢弃。
如果你打算丢弃这些元素,那么没有理由映射到collect
。如果由于某种原因 想要保留None
个实例,那么应将其他实例映射到None
,以便您拥有Some[Element]
。
答案 1 :(得分:2)
我同意m-z collect
在这里是一个很好的选择。您有时也可以选择使用flatMap
,并为所需的值返回Some
,为其他值返回None
。由于Option
被隐式转换为可迭代,flatMap
会将列表展平为您想要的内容:
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)