Scala с использованием foldLeft для вставки терминатора между списком строк
Я написал свое собственное рекурсивное определение 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, но не с терминатором.
2 ответа
Что происходит, так это то, что вы используете термин в качестве начального значения. Но 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 является значение инициализации, которое в этом случае должно быть пустым (уменьшение или что-то подобное было бы более уместным вместо сгиба, оставленного здесь).