2011-07-11 38 views
55

我的方法定義如下所示如何在Scala中匹配數組?

def processLine(tokens: Array[String]) = tokens match { // ... 

假設我想知道第二個字符串是否爲空

case "" == tokens(1) => println("empty") 

不能編譯。我如何去做這件事?

+0

我當你正在努力達成的時候,你真的不明白。測試數組的第二個條目是否爲空字符串,如果是,打印「空」? 其次你的「方法簽名」缺少返回類型歸屬,幷包括一些代碼(即'令牌匹配{}')。 – ziggystar

回答

94

如果你想在陣列上的圖案匹配,以確定是否第二元素是空字符串,你可以做到以下幾點:

def processLine(tokens: Array[String]) = tokens match { 
    case Array(_, "", _*) => "second is empty" 
    case _ => "default" 
} 

_*結合到任何數量的元素,包括沒有。這類似於下面的比賽上列出,這可能是更好地稱爲:

def processLine(tokens: List[String]) = tokens match { 
    case _ :: "" :: _ => "second is empty" 
    case _ => "default" 
} 
3

case聲明不起作用這樣的。這應該是:

case _ if "" == tokens(1) => println("empty") 
+0

如果我想的令牌(1)獨立的檢查,會發生什麼,令牌(2),...? – deltanovember

+0

+1了有效的解決方案,但我不知道,如果'case'關鍵字後面的OP不希望一些複雜的陣列狀的表情,像'(_「」 _)。說'case _'很無聊,但我認爲這是你所能做的一切。也許只是拋棄這場比賽並說出'return tokens(1)==「」':-)。 –

+1

@Ray Toal:參見Ruediger Keller的回答。 –

7

模式匹配可能不是您的示例的正確選擇。你可以簡單地做:

if(tokens(1) == "") { 
    println("empty") 
} 

模式匹配更approriate像案例:

for(t <- tokens) t match { 
    case "" => println("Empty") 
    case s => println("Value: " + s) 
} 

其打印的東西每個令牌。

編輯:如果你想檢查是否存在任何令牌,該令牌是一個空字符串,你也可以嘗試:

if(tokens.exists(_ == "")) { 
    println("Found empty token") 
} 
+1

這絕對有效,但似乎是做事情的程序性方式。我試圖用功能性術語來思考 – deltanovember

+0

是的,因爲你的問題要求程序上的答案。對於更多功能的方法,您可以將每個元素映射到字符串選項,當字符串爲空時,該選項將爲無。您也可以將該行包裝在地圖(或案例類)中以停止顯式地使用索引。 – paradigmatic

+6

@deltanovember的'println'是什麼使你的代碼的程序。您的明顯的混亂的事實,'if'塊是表達式,而不是語句,Scala中(即,它們返回一個值,因此,是完全功能性的)的莖。關於使用「if」表達式而不是模式匹配,本質上沒有任何過程。 –

4

什麼是格外有趣的是,你可以使用一個別名通過_*的東西相匹配的東西,如

val lines: List[String] = List("Alice Bob Carol", "Bob Carol", "Carol Diane Alice") 

lines foreach { line => 
    line split "\\s+" match { 
    case Array(userName, [email protected]_*) => { /* Process user and his friends */ } 
    } 
}