2013-10-18 10 views
6

2つのシーケンスをマージして並べ替えようとしています。2つのシーケンスをスケーラで整然としたやり方で結合する

val seq1 = Seq(1,3,5,7,9) 
    val seq2 = Seq(2,4,6,8) 
    var arr = Seq[Int]() 
    for(b <- seq2) 
    { 
    for(a <- seq1) 
    { 
     if(a < b) 
     arr = arr :+ a 
     else 
     { 
     arr = arr :+ b;break; 
     } 
    } 
    } 
    println(arr) 

私がする必要性を必要と出力:

Seq(1,2,3,4,5,6,7,8,9)  

しかし、それは休憩がScalaで動作しないようです以下は、私が書いたコードです。私はその言語に対して比較的新しいです。この操作を実行する最良の方法は何でしょうか?

+0

、および場合これはおそらくエラーになるでしょう。あれは正しいですか? – Luciano

答えて

16

最も簡単な方法は、おそらくこのようになります:seq1seq2は、他のいくつかのタイプが含まれている場合は、そのタイプにOrderingを提供する必要があります

(seq1 ++ seq2).sorted 

。あるいは、sortByメソッドを使用し、Orderingが暗黙のうちに見つけることができるため、他のタイプの要素に各要素をマッピング:

(seq1 ++ seq2).sortBy(_.toDate) 
+0

上記の例でInt型の要素の代わりに日付(正確にはLocalDate型の要素)があったらどうなりますか?ソートされたメソッドは日付に対しては機能しません。何を指示してるんですか? –

+0

sortByの2種類の方法がありますか? toDateのように、優先権に?それで、それは最初に日付に、その後に優先権に命令されるでしょうか? –

+1

'sortBy(x =>(x.toDate、x.toPriority))' –

1

個々の順序を維持しながら、二つの配列をインターリーブするには、使用することができます。

scala> seq1.zip(seq2).flatMap(pair => Seq(pair._1,pair._2)) 
res1: Seq[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) 

しかし、不等長さのシーケンスでは、これは長いシーケンスの余分な要素を失います。これはもう少し努力して並べ替えることができます(2つのリストのうち長いほうを見つけ、longer.drop(shorter.length)を追加してください)。

+0

すみません。私は最後に要素 '9'を追加するのを忘れていました。 –

5

次のようにも非インターリーブシーケンスのために働く:

def mergeSorted[E: Ordering](x: Seq[E], y: Seq[E]): Seq[E] = { 
    val ordering = implicitly[Ordering[E]] 
    @tailrec 
    def rec(x: Seq[E], y: Seq[E], acc: Seq[E]): Seq[E] = { 
    (x, y) match { 
     case (Nil, Nil) => acc 
     case (_, Nil) => acC++ x 
     case (Nil, _) => acC++ y 
     case (xh :: xt, yh :: yt) => 
     if (ordering.lteq(xh, yh)) 
      rec(xt, y, acc :+ xh) 
     else 
      rec(x, yt, acc :+ yh) 
    } 
    } 
    rec(x, y, Seq()) 
} 

パフォーマンス上の理由から、おそらくビルダーを使用すると思いますので、予めご了承ください(対:+、+は逆:,)。

3

私はCaringDevのソリューション@見つけることとBuilderを使用するように適応させるために幸せだった:**私はそれが2つの入力シーケンス**がすでにソートされていることを、あなたの質問に強調する価値だと思う

def mergeSortedBuilder[E: Ordering](x: Seq[E], y: Seq[E])(implicit ordering: Ordering[E]): Seq[E] = { 
    @tailrec 
    def rec(x: Seq[E], y: Seq[E], acc: Builder[E, Seq[E]]): Builder[E, Seq[E]] = { 
    (x, y) match { 
    case (Nil, Nil) => acc 
    case (_, Nil) => acC++= x 
    case (Nil, _) => acC++= y 
    case (xh :: xt, yh :: yt) => 
     if (ordering.lteq(xh, yh)) 
     rec(xt, y, acc += xh) 
     else 
     rec(x, yt, acc += yh) 
    } 
} 
rec(x, y, Seq.newBuilder).result 
} 
関連する問題