Reputation: 1690
I have a list of words in F# and a string input. I want to see if any of the words in the list are contained in the string. If I was using C# Id run a foreach loop on each word in the string.split and run an List.contains comparison. I have come up with the following code so far, but can't seem to access List.contains on the value 'str'
let checkforvalue(x:string) =
for str in x.Split(' ') do
match str with commandList -> Console.WriteLine(str + " found: " + x)
()
The current function always returns true and executes the Console.WriteLine method.
Any ideas what I am doing wrong?
Upvotes: 1
Views: 714
Reputation: 6008
I think you have misunderstood the semantics of the pattern matching syntax. The match str with commandList
will not go through the commandList
and see if str
'matches' any of the strings in commandList
.
Instead, it will try to destructure str
into a pattern that you provide, which in your case says nothing about the actual structure, so anything will effectively be matched and bound to the name commandList
.
As @JohnPalmer pointed out, this will just shadow your other commandList
binding. But anyway, I don't think pattern matching is a proper way to solve your problem, even (especially?) if you go as far as using Active Patterns.
Here's how you could solve this problem instead:
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)
Upvotes: 2
Reputation: 47904
This doesn't answer your question directly, but you're essentially doing set intersection, which can be expressed more simply:
Set.intersect (set (x.Split(' '))) (set commandList)
Upvotes: 6
Reputation: 25516
The problem here is that commandList
when used how you have used it creates a new variable which shadows the old.
You probably want something like
let checkforvalue(x:string) =
for str in x.Split(' ') do
match str with s when s=commandList -> Console.WriteLine(str + " found: " + x)
if commandList
is a string
If it is a list you could do:
let checkforvalue(x:string) =
for str in x.Split(' ') do
if List.exists (fun s -> s=str) commandlist then Console.WriteLine(str + " found: " + x)
Upvotes: 2