2010-02-26 82 views
1

我想构建一个通用的数字函数来获取浮点数组,然后返回一个元组数组,将数组分解成N个等距距离,其中每个元组代表每个范围的下限和上限。结果数组中第一个元组的第一个元素应该是输入数组的最小值,结果数组中最后一个元组的第二个元素应该是输入数组的最大值。如何从数组中创建间隔的元组?

我的问题是,我试图解决这个使用模式匹配,我的代码编译,但它没有创建任何东西(?)我得到一个警告说,第三模式永远不会匹配。我很困惑,因为我认为我涵盖了所有的情况 - 第一,最后,然后介于两者之间。在此先感谢有关如何解决此问题的任何好建议。

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; 
+1

这是干什么用的?这似乎是功课。 – gradbot 2010-02-26 17:48:52

+2

什么学校用一种还没有正式发布的语言做作业? – 2010-03-01 18:40:29

+0

不是功课。我有很多财务时间序列数据,我经常想要检查数据的整体分布。能够有一个让我返回N个区间的通用函数可以更容易地生成直方图。我一直在使用ZedGraph和C#,并试图将代码移植到F#,因为我可以看到它最终使我的工作变得更容易。 – 2010-03-02 18:17:29

回答

5

由于maxGroup与任何值匹配,第三个模式永远不会匹配。只有文字值可用于匹配块,不太直观。您正在创建绑定到匹配模式的本地作用域变量名称。你想使用一个when子句,像这样:

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

这简单地匹配任何值,当我等于maxGroup。

克里斯·史密斯有一些例子,更好地展示这一特性:http://blogs.msdn.com/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx

+0

+1。我已经被这个人咬了好几次了。记住你正在处理匹配*模式*,不匹配*值*是关键。 – cfern 2010-02-26 16:25:15

+0

谢谢 - 这是诀窍! – 2010-02-26 18:04:41

+0

还有一件事 - 模式中的“n”需要用“i”替换,以便实际返回我期待的间隔...... – 2010-02-26 18:07:18

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) 
相关问题