1

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 メソッドを実行します。

私が間違っていることは何ですか?

4

3 に答える 3

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)
于 2013-07-18T02:23:27.963 に答える
2

パターン マッチング構文のセマンティクスを誤解していると思います。はmatch str with commandListを通過せず、のいずれかの文字列と「一致」するかcommandListどうかを確認します。strcommandList

代わりに、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 に答える