2013-07-18 21 views
1

我有一個F#中的單詞列表和一個字符串輸入。我想查看列表中的任何單詞是否包含在字符串中。如果我使用C#Id,請在string.split中的每個單詞上運行foreach循環,然後運行List.contains比較。我想出了下面的代碼,到目前爲止,但似乎無法訪問的價值「STR」需要測試字符串,例如F#中的列表中的單詞。

let checkforvalue(x:string) = 
    for str in x.Split(' ') do 
    match str with commandList -> Console.WriteLine(str + " found: " + x) 
() 

當前函數總是返回true,並執行Console.WriteLine命令方法List.contains。

任何想法我做錯了什麼?

回答

2

我認爲你誤解了pattern matching語法的語義。 match str with commandList將不會經過commandList並查看str是否匹配commandList中的任何字符串。

取而代之的是,它會嘗試將str解構成您提供的模式,在您的案例中,對實際結構沒有提供任何說明,因此任何內容都將與名稱commandList進行有效匹配並綁定。

正如@JohnPalmer指出的那樣,這隻會影響您的其他commandList綁定。但無論如何,我不認爲模式匹配是解決您的問題的正確方法,甚至(尤其是?)如果您使用Active Patterns

這裏是你如何解決這個問題,而不是:

let checkForValue (str : string) commandList = 
    // convert to set for better performance 
    let commands = Set.ofList commandList 
    str.Split(' ') |> Seq.exists (fun x -> Set.contains x commands) 
+0

感謝您的深入解釋。我來自OO背景,F#不僅僅是學習一種新的語法。 – ChargerIIC

2

這裏的問題是,commandList使用時如何使用它創建一個新的變量,它會影響舊的。

你可能要像

let checkforvalue(x:string) = 
    for str in x.Split(' ') do 
    match str with s when s=commandList -> Console.WriteLine(str + " found: " + x) 

如果commandList是一個字符串

如果它是你可以做一個列表:

let checkforvalue(x:string) = 
    for str in x.Split(' ') do 
    if List.exists (fun s -> s=str) commandlist then Console.WriteLine(str + " found: " + x) 
6

這並不直接回答你的問題,但你基本上在做交集,可以更簡單地表達:

Set.intersect (set (x.Split(' '))) (set commandList) 
相關問題