1

次の (変更可能な) 例を考えてみましょう。

let getRegexFlax flags =
    let mutable res = RegexOptions.None
    for ch in flags do
        match ch with
        | 's' ->  res <- res ||| RegexOptions.Singleline
        | 'x' ->  res <- res ||| RegexOptions.IgnorePatternWhitespace
        | 'i' ->  res <- res ||| RegexOptions.IgnoreCase
        | 'm' ->  res <- res ||| RegexOptions.Multiline
        | _   ->  raise (Exception("invalid flag"))
    res

この例を使用して、私たちがよく遭遇する状況を例示しました。アイデアは単純です。文字列 (または任意の複雑な条件) に基づいて、0 個以上の列挙型フラグを組み合わせる必要があります。

それを行う最も簡単な方法は、上記のようにミュータブルを使用することだと思います。ミュータブルを使用しない場合、他にも無数の方法を考えることができますが、どれも非常にきれいではないようです。

  • 戻りフラグを組み合わせた再帰関数 (面倒)
  • enum.CombineDon Symeが示唆するように、各配列エントリにif条件またはパターンマッチを使用します(醜い)
  • |||それぞれが条件を持っている(これも醜い)組み合わせ式の長い範囲

できればパターンマッチングを使用し、もちろん可変性を使用しない、より単純で直接的な方法があると確信しています。1日の遅い時間かもしれませんが、今は思いつきません。誰か光を見せてくれませんか?

4

2 に答える 2

3

私は次のようなことをします:

let chartoflag ch= 
    match ch with
    | 's' ->   RegexOptions.Singleline
    | 'x' ->   RegexOptions.IgnorePatternWhitespace
    | 'i' ->  RegexOptions.IgnoreCase
    | 'm' ->  RegexOptions.Multiline
    | _   ->  raise (Exception("invalid flag"))

flags |> Seq.map chartoflag |> Seq.fold (|||) RegexOptions.None
于 2014-11-07T01:47:51.877 に答える
1

関数を使用できますSeq.fold(フラグが文字のコレクションであると仮定します)

let getRegexFlax1 flags =
    flags 
    |> Seq.fold (fun acc ch -> 
                    match ch with
                    | 's' ->  acc ||| RegexOptions.Singleline
                    | 'x' ->  acc ||| RegexOptions.IgnorePatternWhitespace
                    | 'i' ->  acc ||| RegexOptions.IgnoreCase
                    | 'm' ->  acc |||  RegexOptions.Multiline
                    | _   ->  failwith "invalid flag") RegexOptions.None
于 2014-11-07T01:47:32.107 に答える