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

我用这个例子来举例说明我们经常遇到的情况。这个想法很简单:基于字符串(或任何复杂条件),您需要组合零个或多个枚举标志。

我认为,最简单的方法就是像上面那样使用 mutable。如果你不使用 mutable,我可以想到无数其他方法,但似乎没有一个很干净:

  • 结合返回标志的递归函数(繁琐)
  • enum.Combine正如 Don Syme 所建议的那样,每个数组条目中都有一个 if 条件或模式匹配(丑陋)
  • 很长范围的|||组合表达式,每个表达式都有一个条件(也很丑陋)

我确信有一种更简单、更直接的方法,最好是模式匹配,当然,没有可变性。可能是一天中的晚些时候,但我现在根本想不起来,谁能给我指点灯?

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 回答