我有一个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
}
答案 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
并使用map
或for
代替{{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