Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 斯卡拉“;功能性;使用';“不良嵌套”;创建格式良好的XML_Scala_Functional Programming_Scala Collections - Fatal编程技术网

Scala 斯卡拉“;功能性;使用';“不良嵌套”;创建格式良好的XML

Scala 斯卡拉“;功能性;使用';“不良嵌套”;创建格式良好的XML,scala,functional-programming,scala-collections,Scala,Functional Programming,Scala Collections,抱歉,如果这是常见问题,我在任何地方都找不到。这可能是一个新手Scala和/或函数式编程问题。我有很多Java和OO的经验,但我对Scala和FP是新手 假设我有一个列表,其中可能有: a、 b,b,c1,b,d,c2,d,a,ce,b,a,c1,b,ce,a,b 现在,我将处理这个列表并返回一个XML树(scala.XML.NodeSeq或其他)。棘手的部分是,我需要用一个包含以下项目的范围来替换c的任何情况,直到下一个ce。更复杂的是必须处理嵌套,但遇到的任何“ce”项都需要关闭所有挂起的标

抱歉,如果这是常见问题,我在任何地方都找不到。这可能是一个新手Scala和/或函数式编程问题。我有很多Java和OO的经验,但我对Scala和FP是新手

假设我有一个列表,其中可能有:

a、 b,b,c1,b,d,c2,d,a,ce,b,a,c1,b,ce,a,b

现在,我将处理这个列表并返回一个XML树(scala.XML.NodeSeq或其他)。棘手的部分是,我需要用一个包含以下项目的范围来替换c的任何情况,直到下一个ce。更复杂的是必须处理嵌套,但遇到的任何“ce”项都需要关闭所有挂起的标记

所以我想把这样的事情说出来:

<a/> <b/> <b/> <span style="style1"> <b/> <d/> <span style="style2"> <d/> <a/> </span> </span> <b/> <a/> <span style="style1"> <b/> </span> <a/> <b/> 这是在Scala中实现的,我更愿意以“纯功能的方式”并使用Scala最佳实践来实现这一点。我很沮丧,我无法理解这一点


谢谢。

为胜利做一些递归:

  import scala.xml._
  import scala.annotation.tailrec

  val list = List("a", "b", "b", "c1", "b", "d", "c2", "d", "a", "ce", "b", "a", "c1", "b", "ce", "a", "b")

  case class Processor(value: NodeSeq = Nil, rest: List[String] = Nil, isSub: Boolean = false)

  @tailrec
  def toXml(processor: Processor): Processor = 
    processor.rest match {
      case head::tail if(head == "ce") =>   
        if(processor.isSub) Processor(processor.value, processor.rest)        
        else toXml(Processor(processor.value, tail))

      case head::tail if(head.startsWith("c")) => 
        val result = toXml(Processor(Nil, tail, true)) 
        toXml(processor.copy(value = processor.value ++ <span>{result.value}</span>, rest = result.rest))  

      case head::tail => toXml(processor.copy(value = processor.value ++ Elem(null, head, null, TopScope), rest = tail))

      case Nil => processor
    }

  def toXml(input: List[String]): NodeSeq = toXml(Processor(Nil, input)).value


scala> toXml(list).toString
res28: String = <a></a><b></b><b></b><span><b></b><d></d><span><d></d><a></a></span></span><b></b><a></a><span><b></b></span><a></a><b></b>
导入scala.xml_
导入scala.annotation.tailrec
val list=列表(“a”、“b”、“b”、“c1”、“b”、“d”、“c2”、“d”、“a”、“ce”、“b”、“a”、“c1”、“b”、“ce”、“a”、“b”)
案例类处理器(值:NodeSeq=Nil,rest:List[String]=Nil,isSub:Boolean=false)
@泰勒克
def toXml(处理器:处理器):处理器=
处理器.rest匹配{
案例头部::尾部如果(头部==“ce”)=>
if(processor.isSub)processor(processor.value,processor.rest)
else-toXml(处理器(Processor.value,tail))
case head::tail if(head.startsWith(“c”))=>
val结果=toXml(处理器(零、尾、真))
toXml(processor.copy(value=processor.value++{result.value},rest=result.rest))
case head::tail=>toXml(processor.copy(value=processor.value++Elem(null,head,null,TopScope),rest=tail))
case Nil=>处理器
}
def-toXml(输入:List[String]):NodeSeq=toXml(处理器(Nil,输入)).value
scala>toXml(列表).toString
res28:字符串=

我怀疑列表不仅仅是孤立存在的,它是以文件中的行、逗号分隔的值字符串或其他格式开始的——然后根据需要拆分它以生成列表

您可以从原始输入开始,然后重新表述问题,而不是这样做:

给定这个原始输入,我如何处理它以生成以下内容 树结构

(我将以XML的形式输出)

答案是“使用Scala的解析器”,这将为您提供一些漂亮的声明性代码。您也会发现它比您自己滚动的任何东西都更易于维护。

我喜欢使用
foldLeft
。您只需要记录有多少嵌套级别

val cN = """c(\d+)""".r
def encode(l: List[String]) = l.foldLeft("" -> 0) {
    case ((acc, nesting), "ce")      => (acc + "</span>" * nesting, 0)
    case ((acc, nesting), cN(style)) =>
        (acc + """<span style="%s">""".format(style), nesting + 1)
    case ((acc, nesting), el)        => (acc + "<%s/>".format(el), nesting)
}._1
val cN=“”c(\d+)”。r
def encode(l:List[String])=l.foldLeft(“->0){
大小写((acc,嵌套),“ce”)=>(acc+“”*嵌套,0)
案例((acc,嵌套),cN(样式))=>
(acc+)。格式(样式),嵌套+1)
大小写((acc,嵌套),el)=>(acc+“”。格式(el,嵌套)
}._1

这将返回一个
字符串
,您可以稍后轻松地将其转换为
XML

我现在正在打电话,无法提供真实答案。但在其他人回答之前,让我暗示一下。你应该打电话给名单上的foldLeft。这将允许您在遍历列表时将多个元素折叠为单个元素。列表条目是字符串,还是仅使用a、b等作为其他数据类型的占位符?此外,数据的格式是否正确?例如,你能在c1之后得到一个c3,或者连续得到两个c2吗?cN和其他回答之间是否总是存在中间值?其他回答有用,但我最终选择了这个解决方案的一个变体。我能够向case对象添加其他属性,这有助于我以纯功能的方式跟踪其他信息(我的帖子是我真实项目的简化版本)。非常感谢大家的帮助。