Scala列表逻辑

时间:2016-02-23 23:56:00

标签: scala

我有列表(2,5,7,15,10),预期结果是(2,10,70,1050,10500)实际上它是前面元素的乘法例如(2,2 * 5,2) * 5 * 7,2 * 5 * 7 * 15,2 * 5 * 7 * 15 * 10)。我试过这个半烘焙的解决方案,但似乎我对foldLeft感到困惑。

任何帮助将不胜感激。

val lis =   List(2, 5, 7, 15, 10)               //> lis  : List[Int] = List(2, 5, 7, 15, 10)
 lis.head                                     //> res0: Int = 2
 lis.drop(1)                                  //> res1: List[Int] = List(5, 7, 15, 10)
 lis.tail                                     //> res2: List[Int] = List(5, 7, 15, 10)
 lis.drop(1).foldLeft(lis) {

         (r,c) =>
         println(r,c)
         r.tail



 }                                            //> (List(2, 5, 7, 15, 10),5)
                                              //| (List(5, 7, 15, 10),7)
                                              //| (List(7, 15, 10),15)
                                              //| (List(15, 10),10)
                                              //| res3: List[Int] = List(10)

2 个答案:

答案 0 :(得分:8)

解决此问题的一种方法是使用inits

scala> val list = List(2, 5, 7, 15, 10)
list: List[Int] = List(2, 5, 7, 15, 10)

scala> list.inits.foreach(println)
List(2, 5, 7, 15, 10)
List(2, 5, 7, 15)
List(2, 5, 7)
List(2, 5)
List(2)
List()

这表明以下单行:

scala> list.inits.map(_.product).toList.init.reverse
res1: List[Int] = List(2, 10, 70, 1050, 10500)

使用scanLeft也可以更简洁有效地解决这个问题:

scala> list.scanLeft(1)(_ * _).tail
res2: List[Int] = List(2, 10, 70, 1050, 10500)

一般情况下,如果您有类似折叠的东西,但想要保留中间累积值,scanLeft是可行的方法。

答案 1 :(得分:0)

您可以折叠成List

list.foldLeft(List.empty[Int]) { 
  case (Nil, x) => List(x)
  case (head :: tail, x) => (head*x) :: head :: tail
}.reverse