scala列表操作:这是好的scala吗?

scala列表操作:这是好的scala吗?,scala,immutability,mutable,Scala,Immutability,Mutable,我在scala中编写了一些代码来解析相对(文件)路径,请参见下面的代码。我将路径存储为字符串列表,当我计算一个相对路径时,我使用一个可变列表变量,在该变量中我存储我工作的列表的修改副本 我有一种直觉,这可能不是最好的方法,或者是吗?我应该使用可变列表并处理它吗?或者我应该只使用不可变列表,完全不使用变量和函数版本吗?“相对”方法应该如何编写 class PathInfo(e: List[String]) { val elements=e; def relative(s : S

我在scala中编写了一些代码来解析相对(文件)路径,请参见下面的代码。我将路径存储为字符串列表,当我计算一个相对路径时,我使用一个可变列表变量,在该变量中我存储我工作的列表的修改副本

我有一种直觉,这可能不是最好的方法,或者是吗?我应该使用可变列表并处理它吗?或者我应该只使用不可变列表,完全不使用变量和函数版本吗?“相对”方法应该如何编写

class PathInfo(e: List[String]) {

    val elements=e;

    def relative(s : String) :PathInfo= relative(PathInfo.fromString(s));

    def relative(that : PathInfo) : PathInfo = {
        var list : List[String]=List();
        for (item <- elements) {
            list = list :+ item;
        }
        for (item <- that.elements) {
            item match {
                case "." => ;
                case ".." => list = list dropRight(1);
                case other => list = list :+ other;
            }
        }
        new PathInfo(list);
    }

    override def toString : String = {
        elements.mkString("/");
    }

}

object PathInfo {
    def fromString(s : String) : PathInfo={
        new PathInfo(List.fromString(s,'/'));
    }
}
类路径信息(e:List[String]){
val元素=e;
def relative(s:String):PathInfo=relative(PathInfo.fromString);
def relative(that:PathInfo):PathInfo={
变量列表:list[String]=list();
对于(项目列表=列表右键(1);
案例其他=>list=list:+other;
}
}
新路径信息(列表);
}
重写def toString:字符串={
元素。mkString(“/”);
}
}
对象路径信息{
def fromString(s:String):路径信息={
新的路径信息(List.fromString,“/”);
}
}

通常,表单的循环:

var foo = initialFoo
for (x <- xs) foo = f(foo, x)
在此特定情况下,foldLeft版本如下所示:

val list = that.elements.foldLeft(this.elements) { (xs, x) => 
  x match {
    case "." => xs
    case ".." => xs init
    case other => xs :+ other
  }
}

顺便说一句,不需要迭代元素列表来复制它的初始值
list
-它是一个不可变的列表,因此可以安全地共享。

通常,表单的循环:

var foo = initialFoo
for (x <- xs) foo = f(foo, x)
在此特定情况下,foldLeft版本如下所示:

val list = that.elements.foldLeft(this.elements) { (xs, x) => 
  x match {
    case "." => xs
    case ".." => xs init
    case other => xs :+ other
  }
}

顺便说一句,不需要迭代元素列表来复制它的初始值
list
-它是一个不可变的列表,因此可以安全地共享。

我只想对David的建议做一个小的编辑;我发现我更喜欢直接解构折叠中元组的元素:

val list = that.elements.foldLeft(this.elements) { 
  case (xs, ".")  => xs
  case (xs, "..") => xs init
  case (xs, x)    => xs :+ x
}

现在,这里有一个谜题。这很有效,而且以一种可爱的方式实现了……但是,你能找出为什么一个PartialFunction[(List[String],String),List[String]]被提升为Function2[List[String],String,List[String]]?:)

我只是想对David的建议做一个小的修改;我发现我更喜欢直接解构foldLeft中的元组元素:

val list = that.elements.foldLeft(this.elements) { 
  case (xs, ".")  => xs
  case (xs, "..") => xs init
  case (xs, x)    => xs :+ x
}

现在,这里有一个难题。这是可行的,而且以一种可爱的方式。。。但是,您能理解为什么PartialFunction[(List[String],String),List[String]]被提升为Function2[List[String],String,List[String]]吗

记录你的函数所做的事情,这是每种语言的好风格,然后有人可能会帮助你记录你的函数所做的事情,这是每种语言的好风格,然后有人可能会帮助你我喜欢这个解决方案,它很优雅。在我看来,这是一个“迷你模式”,如果你想用不可变对象编程,你需要学习它。我喜欢这个解决方案,它很优雅。在我看来,这是一个“迷你模式”,如果你想用不可变对象编程,你需要学习它。很酷,我没有意识到你能做到这一点。它特别适合折叠贴图:Map(“a”->1)。foldLeft(“”{case(res,(str,I))=>res+”;“+str+”:“+I}很酷,我没有意识到你能做到这一点。这对于像折叠贴图这样的事情特别好:Map(“a”->1)。foldLeft(“”{case(res,(str,I))=>res+”;“+str+”:“+I}”