如何从数组创建一个间隔元组?

时间:2010-02-26 16:01:58

标签: f#

我正在尝试构建一个通用数值函数来获取一个浮点数组,然后返回一个元组数组,将数组分解为相等距离的N个范围,其中每个元组表示每个范围的下限和上限。结果数组中第一个元组的第一个元素应该是输入数组的最小元素,结果数组中最后一个元组的第二个元素应该是输入数组的最大元素。

我的问题是我正在尝试使用模式匹配解决这个问题,我的代码编译,但它没有创建任何东西(?)我得到一个警告说第3个模式永远不会匹配。我很困惑,因为我以为我已经覆盖了所有案例 - 第一,最后,然后介于两者之间。提前感谢有关如何修复此代码的任何好主意。

let rand1000 = [| for i in 1..1000 do yield rnd.NextDouble() |]


let intervals (arr: float array) (n : int) =
    let L = Array.min(arr);
    let U = Array.max(arr);
    let increment = U - L / (float n);
    let maxGroup = n-1;
    [| for i in 0..maxGroup do 
          let range = match i with
                      | 0 -> L, L + increment
                      | maxGroup -> L + (float n) * increment, U
                      | _ -> L + (float n) * increment, L + (float (n + 1)) * increment
          yield range
    |]

let inters = intervals rand1000;

2 个答案:

答案 0 :(得分:5)

第三种模式永远不会匹配,因为maxGroup匹配任何值。只有字面值可以在匹配块中使用,不是很直观。您正在创建绑定到匹配模式的本地范围变量名称。您想使用when子句,如下所示:

| _ when i = maxGroup -> L + (float n) * increment, U

当i等于maxGroup时,这只会匹配任何值。

Chris Smith有一些示例可以更好地演示此功能:http://blogs.msdn.com/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx

答案 1 :(得分:0)

dice函数将序列整理成一串n个元素:

let dice n xs =
  Seq.mapi (fun i x -> i/n, x) xs
  |> Seq.groupBy fst
  |> Seq.map (fun (_, xs) -> Seq.map snd xs)

minMaxIntervals函数使用dice整理序列,然后在生成的时间间隔内映射minmax函数:

let minMaxIntervals n xs =
  dice n xs
  |> Seq.map (fun xs -> Seq.min xs, Seq.max xs)