Scala - 列表中的每个第2个元素加倍

时间:2017-10-12 01:38:28

标签: scala functional-programming

我想编写一个函数,给定一个Int列表,返回一个列表,其中每个第二个元素都加倍了。

在Haskell中,解决方案似乎很简单;

double = zipWith ($) (cycle [id,(*2)])请参阅here

在Scala中最常用的方法是什么?

6 个答案:

答案 0 :(得分:4)

一种方法是使用此Stream创建zip个和两个,然后List Stream List。这会通过此map创建List对:val oneTwoCycle: Stream[Int] = List(1, 2).toStream #::: oneTwoCycle val data = (1 to 10).toList val altDoubled = data.zip(oneTwoCycle).map(x => x._1 * x._2) // List(1, 4, 3, 8, 5, 12, 7, 16, 9, 20) 并将元组元素相乘。

ExUnit.CaptureIO.capture_io

答案 1 :(得分:1)

可能不是最惯用的,但一个解决方案可能是

scala> def double(list: List[Int]) = list.zipWithIndex.map{case (elem, index) => if(index==1) elem*2 else elem}
double: (list: List[Int])List[Int]

scala> double(List(1, 2, 3))
res7: List[Int] = List(1, 4, 3)

或者,如果您希望同一列表中的每个第二个元素加倍,

scala> def double(list: List[Int]) = list.zipWithIndex.map{case (elem, index) => if((index+1)%2 == 0) elem*2 else elem}
double: (list: List[Int])List[Int]

scala> double(List(1, 2, 3, 4, 5, 6))
res2: List[Int] = List(1, 4, 3, 8, 5, 12)

答案 2 :(得分:1)

你可以试试这个:

scala> val list = (1 to 10).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> list.view.zipWithIndex.map(x => if(x._2 %2 != 0) 2*x._1 else x._1).toList
res6: List[Int] = List(1, 4, 3, 8, 5, 12, 7, 16, 9, 20)

答案 3 :(得分:1)

不完全简洁的Haskell,但它非常易读

(1 to 10).zipWithIndex.map { case (num, i) =>
  if (i % 2 == 1) num * 2 else num
}

答案 4 :(得分:1)

到目前为止所有的答案都是硬连线来做海报特别要求的(即每隔一个元素加倍),但Haskell实现更加灵活 - 功能列表可以很容易地扩展到做一些不同的事情,比如说,每一个,第二个,第三个元素。

这是一个Scala版本,类似地使用一系列函数循环

val fns = List[Int=>Int](identity, {x => x *2})
val xs = List(1,2,3,4)

def cycle[T](x:List[T]) = Iterator.continually(x).flatten.toIterable
val ys = xs zip cycle(fns)
ys map { case (v, f) => f(v)}

// List(1, 4, 3, 8)

答案 5 :(得分:0)

使用递归和模式匹配编写时不是最短但很有趣。

 def double(xs: List[Int]) =  {
    @scala.annotation.tailrec
    def doubleR(xs: List[Int], acc: List[Int]): List[Int] = xs match{
      case Nil      => acc 
      case h::Nil   => (h +: acc) 
      case h::ht::t => doubleR(t, ht * 2 +: h +: acc)
    }
    doubleR(xs, List[Int]()).reverse
  }

测试

scala> double(List(1,2,3,4,5))
res3: List[Int] = List(1, 4, 3, 8, 5)