2016-02-15 10 views
10

を埋めるために、我々は異なるサイズの次のリストを持っていると仮定しますジップ二つのリスト

val list1 = ("a", "b", "c") 
val list2 = ("x", "y") 

は今、私はこれらの2つのリストをマージし、連結されている文字列要素で新しいリストを作成したいです:

val desiredResult = ("ax", "by", "c") 

私は、here提案として

val wrongResult = (list1, list2).zipped map (_ + _) 

を試してみましたzipは長いリストの要素と一致しない要素を破棄するため、これは意図したとおりに機能しません。

どうすればこの問題を解決できますか? 1つのリストが長い場合、リストを圧縮して "デフォルトの要素"(この場合は空の文字列のように)を与える方法はありますか?

答えて

26

あなたが探している方法は.zipAllです:

scala> val list1 = List("a", "b", "c") 
list1: List[String] = List(a, b, c) 

scala> val list2 = List("x", "y") 
list2: List[String] = List(x, y) 

scala> list1.zipAll(list2, "", "") 
res0: List[(String, String)] = List((a,x), (b,y), (c,"")) 

.zipAllは3つの引数を取ります。

  • this場合
  • でデフォルト値を圧縮するために反復可能(コレクション.zipAllがオンになっています)は短いです
  • 他のコレクションがある場合は、デフォルト値より短く
+1

私はいつも知らない何かがあると思います。 –

+0

ありがとう!これは、このソリューションで動作します: 'list1.zipAll(list2、" "、" ")map({case(y、x)=> y + x})' "、" ")map(_ + _)'となります。 zipAllで短い構文を使用できないのはなぜですか? – ForceOfWill

+1

@ForceOfWill: '(list1、list2).zipped'は' Tuple2Zipped'を返します。['.map'](http://www.scala-lang.org/api/current/index.html#scala.runtime (El1、El2)=> B)(implicitcbf:scala.collection.generic.CanBuildFrom [Repr1、B、To]):To)は 'f:(El1、 El2)=> B'(すなわち、2つの引数をとる関数)である。 'List [A]'の '.map'は' f:A => B'、つまり1つの引数(この場合は 'Tuple2'です)をとります。残念ながら、これは '_ + _'(2つの引数を取る関数)はここでは適用できないことを意味します。 – Marth

2

APIベースの進むべき道は、まだ次のようにインスタンスの(練習として)それを実装することができzipAll

implicit class OpsSeq[A,B](val xs: Seq[A]) extends AnyVal { 
    def zipAll2(ys: Seq[B], xDefault: A, yDefault: B) = { 
    val xs2 = xs ++ Seq.fill(ys.size-xs.size)(xDefault) 
    val ys2 = ys ++ Seq.fill(xs.size-ys.size)(yDefault) 
    xs2.zip(ys2) 
    } 
} 

したがって、例えば

Seq(1,2).zipAll2(Seq(3,4,5),10,20) 
List((1,3), (2,4), (10,5)) 

list1.zipAll2(list2, "", "") 
List((a,x), (b,y), (c,"")) 
デフォルト xdとデフォルト yd値で

再帰バージョン、

def zipAll3[A,B](xs: Seq[A], ys: Seq[B], xd: A, yd: B): Seq[(A,B)] = { 
    (xs,ys) match { 
    case (Seq(), Seq()) => Seq() 
    case (x +: xss, Seq()) => (x,yd) +: zipAll3(xss, Seq(), xd, yd) 
    case (Seq(), y +: yss) => (xd,y) +: zipAll3(Seq(), yss, xd, yd) 
    case (x +: xss, y +: yss) => (x,y) +: zipAll3(xss, yss, xd, yd) 
    } 
} 

関連する問題