1

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

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

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

任何想法我做错了什么?

4

3 回答 3

6

这并不能直接回答你的问题,但你本质上是在做集合交集,可以更简单地表达:

Set.intersect (set (x.Split(' '))) (set commandList)
于 2013-07-18T02:41:43.753 回答
2

这里的问题是,commandList当你使用它时,它会创建一个新变量,它会影响旧变量。

你可能想要类似的东西

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

ifcommandList是一个字符串

如果它是一个列表,你可以这样做:

let checkforvalue(x:string) = 
  for str in x.Split(' ') do
    if List.exists (fun s -> s=str) commandlist then Console.WriteLine(str + " found: " + x)
于 2013-07-18T02:23:27.963 回答
2

我认为您误解了模式匹配语法的语义。match str with commandList不会通过并commandList查看是否str“匹配”中的任何字符串commandList

相反,它将尝试解构str为您提供的模式,在您的情况下,它没有说明实际结构,因此任何内容都将有效地匹配并绑定到 name 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)
于 2013-07-18T08:18:53.600 回答