1

我有一个包含许多未知属性的节点的 NodeSeq。必须验证并重新创建 NodeSeq,并将错误(如果遇到)添加为节点中的属性。

下面的解决方案有效,但我想知道是否有更优雅的方式来实现我的目标?

def validateErrors (nodes:NodeSeq):NodeSeq={

 var newNodes = new Queue[Node]()
   nodes.foreach ( n => {
     var error:Boolean = false
     var errorMessage:String = ""
     //...do many complex validations
     // and get the error status code and error message
     if (error)
       newNodes += AddError(n,errorMessage)
     else
       newNodes +=n       
   })
   newNodes
}

private def AddError (node:Node, message:String ):Node= node match {  
    case elem : Elem => elem % Attribute(None, "color", Text("red"), Null)  %  Attribute(None, "message", Text(message ), Null) //and many more
    case other => other   
}
4

2 回答 2

1

而不是error标志,您可以 bmake errorMessage anOption[String]和整个错误消息创建部分方法。

您还可以使用模式匹配更改 addError 方法以处理没有错误的情况:

private def AddError (node:Node, message:Option[String] ):Node= (node, message) match {  
    case (elem : Elem, Some(m) => elem % Attribute(None, "color", Text("red"), Null)  %  Attribute(None, "message", Text(m), Null) //and many more
    case (other,_) => other   
}

注意:在没有 scala 编译器的情况下键入它,因此可能无法编译,但我希望这个想法变得清晰。

于 2012-08-20T05:50:29.843 回答
1

可能有帮助的一件事是声明newNodes为 aval而不是 avar并使用maporfor而不是foreach迭代nodes并构建新值。更改其他var声明来使用val也很好。使用Option[String]错误消息的消息(如 Jens Schauder 的回答中所建议的)消除了对标志的需要。

val nodes = for (n <- nodes) yield {
  val errorMsg: Option[String] = {
    //...do many complex validations
    // and get the error status code and error message
  }
  errorMsg match {
    case Some(msg) => AddError(n, msg)
    case None => n
  }
}

使用foldLeft(ie /:) 添加所有属性也可能会简化AddError

private def AddError(node: Node, message: String ): Node = node match {  
  case elem: Elem => {
    val attrs = List("color"->Text("red"), "message"->Text(message) /* , ... */)
    (elem /: attrs) { (acc, x) => acc % Attribute(None, x._1, x._2, Null) }
  }
  case _ => node
}

您可能还想考虑在 Attribute 字段中使用case objects 之类的:enum

Attribute(None, AttColor, "red", Null)
Attribute(None, AttMsg, Text(message), Null)

案例类可能会更好(尽管如果Text以多种方式使用,您可能必须添加更多案例):

Attribute(None, Color("red"), Null)
Attribute(None, MsgText(message), Null)
于 2012-08-20T06:13:10.383 回答