2016-03-23 14 views
3

に等しくない長さの二つのリストに参加:は、私は2つのリストを持っているのScala

私がどのように見える新しいリストで、その結果、最初のリストの値として、第2のリストに鍵を交換したい
val list_1 = List((1, 11), (2, 12), (3, 13), (4, 14)) 
val list_2 = List((1, 111), (2, 122), (3, 133), (4, 144), (1, 123), (2, 234)) 

List ((11, 111), (12, 122), (13, 133), (14, 144), (11, 123), (12, 234)) 

これは私の試みです:

object UniqueTest { 
    def main(args: Array[String]){ 
    val l_1 = List((1, 11), (2, 12), (3, 13), (4, 14)) 
    val l_2 = List((1, 111), (2,122), (3, 133), (4, 144), (1, 123), (2, 234)) 
    val l_3 = l_2.map(x => (f(x._1, l_1), x._2)) 
    print(l_3) 

    } 
    def f(i: Int, list: List[(Int, Int)]): Int = { 
    for(pair <- list){ 
     if(i == pair._1){ 
     return pair._2 
     } 
    } 
    return 0 
    } 
} 

これは、その結果:

((11, 111), (12, 122), (13, 133), (14, 144), (11, 123), (12, 234)) 

これを行うには、上記のプログラムが適していますか? Scalaには、この必要性を扱うための組み込み関数、またはこの操作を行う別の方法がありますか?

答えて

4

あなたが作る唯一の本当の過剰な合併症は、この行です:

val l_3 = l_2.map(x => (f(x._1, l_1), x._2)) 

f関数は、ループを繰り返すために命令的スタイルを使用しますrキーを見つけるためのリスト。あなたがこれをやっているといつでも、それはあなたが望むものを示す良いものです。mapです。計算上の複雑さを爆発させるたびにforループを実行すると、マップではO(1)にある特定のキーに対応する値を取得できます。マップでは、キーと値のペアであるリストを、まずキーと値のペアの関係をサポートするデータ構造に変換します。

このように、まず地図を作成する必要があります。 ScalaはtoMapでこれを行うには本当に簡単な方法を提供します:

val map_1 = list_1.toMap 

そして、それは「マッピング」するだけです:

val result = list_2.map { case (key, value) => map_1.getOrElse(key, 0), value) } 

これはあなたのlist_2に各ケースをとり、(最初の値と一致しましたkey)をmap_1のキーに変換し、その値(またはデフォルトの0)を取り出し、キー値タプルの最初の値として配置します。

2

あなたが行うことができます。

val map = l_1.toMap   // transform l_1 to a Map[Int, Int] 
// for each (a, b) in l_2, retrieve the new value v of a and return (v, b) 
val res = l_2.map { case (a, b) => (map.getOrElse(a, 0), b) } 
+0

ありがとうございます。 .mapの後に "{}"と "()"の違いを教えてください。時々、私は.mapの後ろに丸い括弧を使うことができますが、このために "()"は私にコンパイルエラーを与えます。 – Frankie

+0

I、すなわち ''場合タプルのリストに 'toMap'を適用する(A、B)=> ...' ' –

+0

が危険であるパターンマッチングを使用することができるので、私は、その場合には' '{}'使用する:それはいくつかを失うことができるがデータセットに重複した最初の要素がある場合は、タプルを返します。 – Roman

0

最も慣用的な方法は、あなたのニーズに応じてそれらを一緒にビュンしてから変換です:

(list_1 zip list_2) map { case ((k1, v1), (k2, v2)) => (v1, v2) } 
+1

リストの長さが等しくない場合、これは意図したとおりには動作しません。質問に記載されている例を試してみてください。 – helios35

+0

ああ、リストの長さが違うのを忘れてしまった。アプローチは調整することができます、それはまた、エレガントではないでしょう。たとえば、1stリストが短い場合、 '(list_1 ::: list_1 zip list_2)'を実行できます。 – Roman

関連する問題