2017-05-12 15 views
0

リストAとBの2つのリストがあります。リストBを繰り返してAから一致するものを検索したいと思います。一致していない場合は、値。私のリストはもう少し複雑ですが、この単純な例では、働く現実にリストを反復処理し、Scalaの見つからない項目を処理します

val a = List(1,2,3) 
val b = List(1,2,4,5) 
def compute(i:Int):Int = -1*i 
// What I want: val r = List(1,2,-4,-5) 
val r1 = b.foreach(bb => a.find(aa => aa==bb).getOrElse(compute(bb))) 
val r2 = for { 
bb <- b 
r <- a.find(_ == bb).getOrElse(compute(bb)) 
} yield r 

は、私は希望の結果を得るためにさまざまな方法を試してみました。

明らかに私はここで何かを逃しているし、それを間違った方法で攻撃している可能性もあります。誰かが私を正しい方向に向けることを願っています。ありがとう。

+0

あなたの代わりに '' foreach'のmap'を使用しない限り、 'r1'は、' Unit'を返します。あなたの理解の第2行のRHSはコレクション(その 'Int')ではないので、' r2'は計算しません(少なくとも 'List [Int]')。このRHSをyieldに入れるだけで済みます。この場合、 'map'を使うのと同じです。 –

答えて

2

おそらく、セットしてマップします。

val s = a.toSet 
b.map{e => if (s.contains(e)) compute(e) else e} 
+0

'Set'への変換は不要です。 'List'クラスは' contains'関数を持っています。 – chunjef

+0

@chunjef 'Set'への変換の理由は' contains'関数の方が速いからです。したがって、両方のリストが小さい場合は重要ではありませんが、それ以外の場合はパフォーマンスが大幅に向上します。 –

0

これはいかがですか?

b.map(i => { 
    val matches = a.filter(x => x == i) 
    if (matches.nonEmpty) matches.head 
    else compute(i) 
}) 
+0

なぜあなたはあなたが1つの一致する値を見つけたことを知ったら、すべてのコレクションを 'フィルタリング 'しますか? 'a.find(_ == i).getOrElse(compute(i))'はまったく同じ出力を与えますが、終わりの前に値が見つかると 'a'をたどることは避けてください。 –

1
val r = b map (elem => if (a contains elem) elem else compute(elem)) 
関連する問題