web-dev-qa-db-ja.com

Scalaでフィルターとマップを組み合わせる方法は?

Scalaに_List[Int]_があります。リストはList(1,2,3,4,5,6,7,8,9,10)です。リストをfilterしたいので、リストには偶数しかありません。そして、数字を2で多重化したいのですが、可能ですか?

私は質問を明確に説明したと思います。質問がある場合はお問い合わせください。前もって感謝します。

24
eddard.stark

私のコメントで述べているように、collectはあなたが望むことをすべきです:

list.collect{
  case x if x % 2 == 0 => x*2
}

collectメソッドを使用すると、一致する要素の基準を指定する(filter)と、一致する値を変更する(map)ことができます。

@TravisBrownが示唆したように、特に条件がより複雑でガード条件として適していない状況では、flatMapも使用できます。あなたの例ではこのようなもの:

list.flatMap{
  case x if x % 2 == 0 => Some(x*2)
  case x => None
}
44
cmbaxter

内包表記(内部的にmapwithFilterの組み合わせに展開されます)は次のとおりです。

for (x <- xs if x % 2 == 0) yield x*2

すなわち

xs.withFilter(x => x % 2 == 0).map(x => x*2)
7
elm

これはあなたのために仕事をするはずです:

条件がp % 2 == 0(偶数のみを取得するため)。

そして、mapを使用して、それらの偶数に2を掛けます。

var myList = List(1,2,3,4,5,6,7,8,9,10).filter(p => p % 2 == 0).map(p => {p*2})
2
Cacho Santa

@cmbaxterが言ったように、collectはあなたのニーズに完全に合っています。 collectのもう1つの良い点は、クラスでフィルタリングしている場合に結果の型がわかることです。

scala> trait X
// defined trait X

scala> class Foo extends X
// defined class Foo

scala> class Bar extends X
// defined class Bar

scala> val xs = List(new Foo, new Bar, new Foo, new Bar)
// xs: List[X] = List(Foo@4cfa8227, Bar@78226c36, Foo@3f685162, Bar@11f406f8)

scala> xs.collect { case x: Foo => x }
// res1: List[Foo] = List(Foo@4cfa8227, Foo@3f685162)

パーでは、フィルターをそれほどスマートにすることはできません(List[Foo] vs List[X]):

scala> xs.filter { case x: Foo => true; case _ => false }
// res3: List[X] = List(Foo@4cfa8227, Foo@3f685162)
1
om-nom-nom

私はフィルターアプローチが好きです。

val list1 = List(1,2,3,4,5,6,7,8,9,10)
list1.filter(x => x%2 == 0).map(_*2)
1
Dean Sha

古き良き時代の折り目はどうですか?

xs.foldLeft(List[Y]()) { (ys, x) => 
    val z = calculateSomethingOnX(x)
    if (someConditionOnZ(z)) 
        Y(x, z) :: ys
    else 
        ys
}
0
F. P. Freely