我想寫一個函數,給定一個列表Int
s,返回一個列表,其中每個第二個元素已經加倍。Scala - 將列表中的每個第二個元素加倍
在Haskell中,解決方案看起來很簡單;
double = zipWith ($) (cycle [id,(*2)])
見here
請告訴我最習慣的方式在Scala中做到這一點?
我想寫一個函數,給定一個列表Int
s,返回一個列表,其中每個第二個元素已經加倍。Scala - 將列表中的每個第二個元素加倍
在Haskell中,解決方案看起來很簡單;
double = zipWith ($) (cycle [id,(*2)])
見here
請告訴我最習慣的方式在Scala中做到這一點?
可能不是最地道,但一個解決辦法是
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)
'list.zipWithIndex.map {case(elem,1)=> elem * 2 case(elem,_)=> elem}'' – yesemsanthoshkumar
一種方法是創建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)
不是用遞歸和模式匹配寫的最短但有趣的。
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)
你可以試試這個:
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)
不太簡明哈斯克爾,但它是相當可讀
(1 to 10).zipWithIndex.map { case (num, i) =>
if (i % 2 == 1) num * 2 else num
}
所有答案爲止硬連線做海報特別要求的東西(即每第二個元素爲雙精度值),但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)
'list.zipWithIndex.map(X => x._1 *(1+(1&x._2)))' – jwvh