2013-10-18 74 views
6

我想合併兩個序列,使它們保持排序。以下是我寫的代碼:以有序的方式在scala中合併兩個序列

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

最簡單的方法很可能是這樣的:

(seq1 ++ seq2).sorted 

如果seq1seq2含有一些其他類型的,你必須提供該類型的Ordering;或者,可替換地,可使用sortBy方法中,每個元素映射到另一種類型的元件對於其Ordering可以隱含地發現:

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

如果我在上面的例子中有日期(精確到LocalDate類型的元素)而不是int類型的元素,該怎麼辦?方法排序不適用於日期。你有什麼建議? –

+0

有沒有辦法對兩種類型進行排序?像toDate,toPriority?所以它會先訂購到日期再優先訂購? –

+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) 

但是,請注意,對於長度不等的序列,這會丟失較長序列的額外元素。這可以通過更多努力來解決(找到兩個列表中較長的一個,並添加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

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 
} 
相關問題