2017-07-18 140 views
1

前如何使下面的非功能性的,但簡單的代碼更多的功能:退出循環結束

def foo2(iSeq: Seq[Int]): Seq[(Int, Boolean)] = { 
    var seq = Seq[(Int, Boolean)]() 
    iSeq.foreach{ i=> 
     println("i = " + i) 
     val res = (i,i>=0) 
     seq = seq ++ Seq(res) 
     if (res._2==false) return seq 
    } 
    seq 
} 

代碼的想法是循環給出序列,直到第一次測試失敗,沒有進一步的,因爲在真實的代碼測試是昂貴的。返回的seq應包含所有項目,包括失敗的項目。代碼

輸出如下:

scala> foo2(Seq(1,2,-3,4)) 
i = 1 
i = 2 
i = -3 
res3: Seq[(Int, Boolean)] = List((1,true), (2,true), (-3,false)) 

scala> foo2(Seq(1,2,3,4)) 
i = 1 
i = 2 
i = 3 
i = 4 
res4: Seq[(Int, Boolean)] = List((1,true), (2,true), (3,true), (4,true)) 

我做了以下的第一次嘗試:

def fooo(iTail: Seq[Int], resSeq: Seq[(Int,Boolean)]): Seq[(Int,Boolean)] = { 
    if (iTail.isEmpty) return resSeq 
    if (!resSeq.isEmpty && resSeq.last._1<0) return resSeq 
    println("i = " + iTail.head) 
    val res = (iTail.head,iTail.head>=0) 
    val seq = resSeq ++ Seq(res) 
    fooo(iTail.tail, seq) 
    } 

輸出是:

scala> fooo(Seq(1,2,3,4,5),Seq()) 
i = 1 
i = 2 
i = 3 
i = 4 
i = 5 
res0: Seq[(Int, Boolean)] = List((1,true), (2,true), (3,true), (4,true), (5,true)) 

scala> fooo(Seq(1,2,-3,4,5),Seq()) 
i = 1 
i = 2 
i = -3 
res1: Seq[(Int, Boolean)] = List((1,true), (2,true), (-3,false)) 

所以它的工作原理,但有一個更簡潔或「無用」的方式來編碼?

關於性能:代碼使用resSeq.last。在遞歸函數fooo中使用額外的「lastValue」參數比使用resSeq.last更快嗎?

+0

IDK約慣用的,但早期的回報可能不應該在這樣的一條線被擠滿。我會用大括號將它擴展到一個完整的if/else樹,以使它更清晰,可以在不執行函數的下半部分的情況下退出。 – Carcigenicate

回答

1

會這樣嗎?

Seq(1,2,3).takeWhile(_ < 3) 

P.S.謝謝你,@ mrmcgreg,我一直都沒有讀得非常沉悶。包括第一個失敗:

val s = Seq(1,2,3).span(_ < 3) 
s._1 ++ s._2.take(1) 

P.S.而包括比較值:

val s = Seq(1,2,3).map(e => (e, compare(e)).span(test(_._2)) 
s._1 ++ s._2.take(1) 
+0

看起來不太正確,因爲OP想要包含第一個未通過測試的人。 – mrmcgreg

+0

我需要包含比較返回值。在這個例子中,它是布爾型的,但在實際代碼中,它可以具有比true/false更多的值,並且返回的seq必須包含失敗的比較。 – user4955663

+0

您可以變換序列:'Seq(1,2,3).map(e =>(e,f(e))。span(_._ 2 <3)'...... –