我有一个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方法。
任何想法我做错了什么?
答案 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)