2016-06-07 74 views
2

我想編寫一個匹配具有Scala中兩個值的列表的算法。在Scala中具有兩個值的匹配列表

舉例來說,如果我有以下列表:

val list = List(1, 3, 6, 8, 9, 14, 18) 

而且有這樣的兩個值:

val a = 4 

val b = 14 

我想這個名單:

val result = List(6, 8, 9, 14) 

如果是考慮使用Scala的intersect方法,但只適用於兩個列表。

我也想過使用for循環,但這不起作用。

所以我最終不知道如何解決這個問題。

任何人都可以幫助我嗎?

+2

爲什麼不過濾列表? 'list.filter(x => x> = 4 && x <= 14)' – Knight71

回答

6

哦,不過你可以使用intersect,就像這樣:

scala> List(1, 3, 6, 8, 9, 14, 18) intersect (4 to 14) 
res1: List[Int] = List(6, 8, 9, 14) 

而且可以顛倒順序,但由此產生的集合類型是不同的。

scala> 4 to 14 intersect List(1, 3, 6, 8, 9, 14, 18) 
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(6, 8, 9, 14) 

外賣:斯卡拉有很多不同的收藏類型,但他們中的許多人確實很好地一起玩。

+0

第二個例子:如果結果必須是'List',你可以在結果'Vector'上調用'toList'。 – Jesper

+0

你的回答真的幫了我。但讓我們說,我有日曆格式的價值。例如,如果是「2:30」的時間。對於我所看到的我不能使用「to」,因爲它僅適用於整數值。有沒有一個有趣的解決方法? –

+0

@JoãoAlves,很高興我能提供幫助。你是正確的,'Range'集合不能用於日期/時間值。這是一個不同的問題,答案將取決於輸入數據類型。 (string?java.util.Calendar?)明確你想要達到的目標以及迄今爲止所嘗試的內容。 [順便說一句,對你的問題最有用的答案應該被標記爲接受的答案。] – jwvh

1

你可以用下面的語法指定列表:

val list = List(1, 3, 6, 8, 9, 14, 18) 

它將創造scala.collection.immutable.List爲您服務。如果我理解正確的話,你的任務,這oneliner可以解決你的問題:

list filter { element => a to b contains element } 

所以如果一個== 4,和b == 14你會得到:

res0: List[Int] = List(6, 8, 9, 14) 
1

遞歸,模式匹配和衛兵。有趣的部分是後衛if(h >= a && h <= b),其中檢查列表的頭部是否在ab內。如果是這樣,它將被預先記錄在結果列表中。

def slice(a: Int, b: Int, xs: List[Int]): List[Int] = xs match { 
    case Nil       => Nil 
    case h::t if(h >= a && h <= b) => h :: slice(a,b,t) 
    case h::t      => slice(a,b,t) 
} 

測試:

scala> slice(4,14, list) 
res25: List[Int] = List(6, 8, 9, 14) 

scala> slice(18,20, list) 
res26: List[Int] = List(18) 

scala> slice(1,3, list) 
res27: List[Int] = List(1, 3) 

scala> slice(-2,0, list) 
res28: List[Int] = List() 

... 

尾遞歸實現留作練習。 :)

1

使用的理解,

for (i <- xs if i >= 4 && i <= 14) yield i 

爲便於使用考慮這個隱含類,

implicit class OpsList(xs: List[Int]) { 
    def segment(a: Int, b:Int) = for (i <- xs if i >= a && i <= b) yield i 
} 

xs.segment(4,14) 
List(6, 8, 9, 14) 
0

Knight71的評論是最簡潔的,一般情況下,和有效的答案,因爲它將不僅僅是Ints而且不具有潛力LY需要通過整個第二列表的第一個列表中的每個元素搜索:

val result = list filter (x => x >= 4 && x <= 14) 

您可能希望創建一個功能,使你的意圖更爲明顯:

def between(a: Int, b: Int)(x: Int): Boolean = x >= a && x <= b 

val result = list filter between(4, 14) 

這個版本是非常好的如果你把很多不同的標準聯繫在一起得出最終結果。它將應用標準列表與其實施細節分開。