将元素应用于List中的连续元素

bab*_*thy 0 scala

我正在寻找一种方法来应用List中的每个元素及其在Scala中的连续元素,而无需编写嵌套的for循环.基本上我正在寻找一个允许我执行以下操作的List理解:

A = {a, b, c, d}

然后 A' = {ab, ac, ad, bc, bd, cd}

我想过使用map例如,A.map(x => ...)但我无法弄清楚声明的其余部分是什么样的.

希望这一切都有意义.任何帮助将不胜感激.

The*_*aul 6

这似乎是递归评估的自然.因为它将第一个元素添加到列表的其余部分,然后使用应用于列表其余部分的相同内容.

def pairs(xs: List[Char]): List[String] = xs match {
  case Nil | _ :: Nil => Nil
  case y :: ys        => ys.map(z => s"$y$z") ::: pairs(ys)
}

pairs(a) //> res0: List[String] = List(ab, ac, ad, bc, bd, cd)
Run Code Online (Sandbox Code Playgroud)

尾递归

def pairs2(xs: List[Char], acc:List[String]): List[String] = xs match {
  case Nil | _ :: Nil => acc.reverse
  case y :: ys        => pairs2(ys, ys.foldLeft(acc){(acc, z) => s"$y$z"::acc})
}

pairs2(a, Nil)  //> res0: List[String] = List(ab, ac, ad, bc, bd, cd)
Run Code Online (Sandbox Code Playgroud)

或者如果你真的想要理解:

val res = for {(x::xs) <- a.tails
                y <- xs
              } 
            yield s"$x$y"
Run Code Online (Sandbox Code Playgroud)

(返回一个迭代器,所以强制其评估)

res.toList //> res1: List[String] = List(ab, ac, ad, bc, bd, cd)
Run Code Online (Sandbox Code Playgroud)

这表明还有另一种变体,来自于贬低

a.tails.collect{case(x::xs) => xs.map(y=>s"$x$y")}.flatten.toList
//> res2: List[String] = List(ab, ac, ad, bc, bd, cd)
Run Code Online (Sandbox Code Playgroud)