需要测试字符串,例如F#中列表中的单词

时间:2013-07-18 02:16:50

标签: f# comparison match

我有一个F#中的单词列表和一个字符串输入。我想看看列表中是否包含任何单词。如果我正在使用C#Id,则在string.split中的每个单词上运行一个foreach循环并运行List.contains比较。到目前为止,我已经提出了以下代码,但似乎无法访问值'str'上的List.contains

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

当前函数始终返回true并执行Console.WriteLine方法。

任何想法我做错了什么?

3 个答案:

答案 0 :(得分:6)

这不会直接回答你的问题,但你实际上是在设置交集,可以更简单地表达:

Set.intersect (set (x.Split(' '))) (set commandList)

答案 1 :(得分: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)

答案 2 :(得分: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)