Scala 使用 foldLeft 在字符串列表之间插入终止符

Scala using foldLeft to insert terminator between list of strings

我自己写了一个 foldLeft 的递归定义,我想将它与这个函数 joinTerminateLeft 一起使用,它接受一个字符串列表和一个终止符,并用它们创建一个新字符串字符串全部由终止符分隔。

例如带有终止符 ;List("a", "b", "c", "d") 最终会变成 a;b;c;d;

这是我的 foldLeft,我认为它很好,但我的 terminateLeft 出于某种奇怪的原因不起作用,知道吗?

def foldLeft [A,B] (xs:List[A], e:B, f:(B,A)=>B) : B = {
  def auxFoldLeft(xs: List[A], e: B) : B = {
    xs match {
      case Nil => e
      case x::xs => auxFoldLeft(xs, f(e, x))
    }
  }
  auxFoldLeft(xs, e)
}

def joinTerminateLeft (xs : List[String], term : String) : String = {
  def f(s: String, s2: String) : String = s + s2
  xs match {
    case Nil => ""
    case x::xs => x + foldLeft(xs, term, f)
  }
}

当我 运行 joinTerminateLeft 使用 a,b,c,d 时,由于某种原因它在 B 之后停止并输出字符串 c,d 但不带终止符。

发生的情况是您使用术语作为起始值。但是 e 是一个累加器,每次迭代都会添加到最后一次。所以通过一次,你得到 ; + b 但下一次累加器是它的值所以你得到 |b + c

您需要的是不同的功能。不是将值添加到累加器,而是需要将项添加到值,然后将其添加到累加器。

def joinTerminateLeft (xs : List[String], term : String) : String = {
  def f(s: String)(s2: String, s3: String) : String = s2 + s + s3
  xs match {
    case Nil => ""
    case x::xs => x + foldLeft(xs, "", f(term))
  }
}

这是一个有效的片段:

def joinTerminateLeft (xs : List[String], term : String) : String = {
    def f(s: String, s2: String) : String = s + term + s2
    xs match {
        case Nil => ""
        case x::xs => x + foldLeft(xs, "", f)
    }
}

该术语只能在 f 中使用。 foldLeft 的第二个参数是初始化值,在这种情况下应该为空(reduce 或类似的东西会更合适,而不是 fold left 在这里)。