2010-02-26 3 views
1

Я пытаюсь создать общую числовую функцию, чтобы взять массив поплавков, а затем вернуть массив кортежей, который разбивает массив на N диапазонов равного расстояния, где каждый кортеж представляет нижнюю и верхнюю границу каждого диапазона. Первый элемент 1-го кортежа в результирующем массиве должен быть минимальным входным массивом, а второй элемент последнего кортежа в результирующем массиве должен быть максимальным для входного массива.Как создать кортеж интервалов из массива?

Моя проблема в том, что я пытаюсь решить эту проблему с помощью сопоставления с образцом, и мой код компилируется, но он ничего не создает (?). Я получаю предупреждение о том, что третий шаблон никогда не будет соответствовать. Я озадачен, потому что думал, что у меня все покрытые случаи - 1-й, последний, а потом все между ними. Заранее благодарим за любые хорошие идеи о том, как исправить этот код.

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

+2

Какая школа дает домашнее задание на языке, который еще не был официально выпущен? –

+0

Не домашнее задание. У меня много финансовых данных временных рядов, где я часто хочу изучить общее распределение данных. Возможность иметь общую функцию, которая позволяет мне возвращать N количество интервалов, значительно облегчает создание гистограмм. Я использую ZedGraph и C#, и я пытаюсь передать код на F #, потому что я вижу потенциал, который он должен в конечном итоге сделать моей работой намного проще. –

ответ

5

3-й шаблон никогда не будет соответствовать, поскольку maxGroup соответствует любому значению. Только литеральные значения могут использоваться в комбинационных блоках, а не очень интуитивно. Вы создаете имя переменной с локальным областью, привязанное к сопоставленному шаблону. Вы хотите использовать предложение when, например:

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

Это просто соответствует любому значению, когда i равно maxGroup.

Крис Смит имеет некоторые примеры, которые лучше демонстрируют эту особенность: http://blogs.msdn.com/chrsmith/archive/2008/10/03/f-zen-the-literal-attribute.aspx

+0

+1. Я был укушен этим несколько раз. Помните, что вы имеете дело с шаблонами соответствия *, а не с * значениями *. – cfern

+0

спасибо - это трюк! –

+0

еще одна вещь - «n» в шаблонах нужно заменить на «i», чтобы это действительно возвращало промежутки, которые я ожидал ... –

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 для сопоставления последовательности, а затем отображает функции min и max за промежутки времени:

let minMaxIntervals n xs = 
    dice n xs 
    |> Seq.map (fun xs -> Seq.min xs, Seq.max xs) 
Смежные вопросы