2014-11-22 20 views
2

一些项目时,下面的代码遍历节点的一些列表和一些节点创建ParagraphHeading对象:类型检测,映射在一个序列无

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

什么是'child'的类型? – 2014-11-22 21:04:34

回答

4

的使用collect代替map只保留您需要的元素:那是不是你传递给collect被丢弃PartialFunction内定义

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)) 
} 

什么。

如果你只是要丢弃元素,没有理由映射到None。如果你由于某种原因想要保持None实例,那么其他人应该被映射到Some[Element],以便你有Seq[Option[Element]

+0

感谢您的快速回复以及详细和非常有用的解释! – 2014-11-22 21:09:54

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) 
+0

谢谢,我会记住这一点! – 2014-11-22 22:48:21

相关问题