是否有更优雅的方式向Node添加属性?

时间:2012-08-20 04:05:38

标签: scala

我有一个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   
}

2 个答案:

答案 0 :(得分:1)

而不是error标志,您可以使用Option[String]来创建errorMessage,并创建一个方法的整个错误消息。

您还可以使用模式匹配更改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编译器的情况下输入这个,所以可能不会编译,但我希望这个想法变得清晰。

答案 1 :(得分:1)

可能有用的一件事是将newNodes声明为val而不是var并使用mapfor代替{{1}迭代foreach并构建新值。将其他nodes声明更改为使用var也会很好。使用val作为错误消息的消息(如Jens Schauder的回答中所建议的那样)消除了对标志的需要。

Option[String]

使用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)添加所有属性也可以简化/:

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 } 用作属性字段的case object

enum

案例类可能更好(尽管如果以多种方式使用Attribute(None, AttColor, "red", Null) Attribute(None, AttMsg, Text(message), Null) ,您可能需要添加更多案例):

Text