içinde bir hareketli ortalama hesaplamak Hala F # şey grotting üzerinde çalışıyorum - biliyorum sadece diğer dillerden çeviri yerine F # düşünmek için çalışıyoruz çalışıyor.F #
Son zamanlarda, önce ve sonra arasında 1: 1 haritasının olmadığı durumlarda düşündüm. List.map'in düştüğü durumlar.
Bunun bir örneği, n öğelerinin ortalaması alınırken uzunluk uzunluğunun listesi için genellikle len-n + 1 sonuçlarına sahip olduğunuz ortalamaları hareket ettirmektir.
Dışarıdaki gurular için, bunu yapmanın iyi bir yolu var (Jomo Fisher numaralı sorguç dizilimi kullanılarak)?
//Immutable queue, with added Length member
type Fifo<'a> =
new()={xs=[];rxs=[]}
new(xs,rxs)={xs=xs;rxs=rxs}
val xs: 'a list;
val rxs: 'a list;
static member Empty() = new Fifo<'a>()
member q.IsEmpty = (q.xs = []) && (q.rxs = [])
member q.Enqueue(x) = Fifo(q.xs,x::q.rxs)
member q.Length() = (List.length q.xs) + (List.length q.rxs)
member q.Take() =
if q.IsEmpty then failwith "fifo.Take: empty queue"
else match q.xs with
| [] -> (Fifo(List.rev q.rxs,[])).Take()
| y::ys -> (Fifo(ys, q.rxs)),y
//List module, add function to split one list into two parts (not safe if n > lst length)
module List =
let splitat n lst =
let rec loop acc n lst =
if List.length acc = n then
(List.rev acc, lst)
else
loop (List.hd lst :: acc) n (List.tl lst)
loop [] n lst
//Return list with moving average accross len elements of lst
let MovingAverage (len:int) (lst:float list) =
//ugly mean - including this in Fifo kills genericity
let qMean (q:Fifo<float>) = ((List.sum q.xs) + (List.sum q.rxs))/(float (q.Length()))
//get first part of list to initialise queue
let (init, rest) = List.splitat len lst
//initialise queue with first n items
let q = new Fifo<float>([], init)
//loop through input list, use fifo to push/pull values as they come
let rec loop (acc:float list) ls (q:Fifo<float>) =
match ls with
| [] -> List.rev acc
| h::t ->
let nq = q.Enqueue(h) //enqueue new value
let (nq, _) = nq.Take() //drop old value
loop ((qMean nq)::acc) t nq //tail recursion
loop [qMean q] rest q
//Example usage
MovingAverage 3 [1.;1.;1.;1.;1.;2.;2.;2.;2.;2.]
(Belki daha iyi bir yol FIFO devralmasını tarafından MovingAverageQueue uygulamak olurdu?)
Mükemmel, bu bana 'büyümeye' yardımcı olan bir cevaptır - yani, tekerleği yeniden icat etmek yerine zaten var olan şeyleri keşfetmeye! – Benjol
ölü bağlantı, sanırım tüm dokümanlar artık msdn'e taşındı, böylece benzer bir sayfa http://msdn.microsoft.com/en-us/library/dd233209(VS.100).aspx veya http: // msdn olacaktır. .microsoft.com/en-us/library/ee353635 (VS.100) .aspx –
Bunu bir yardımcı program modülüne yerleştirmek için "MovingAverage n (s: seq) =" olarak bildirmek zorunda kaldım. tip sistemini yerleştirmek için arama sitesi. Anlayabildiğim kadarıyla, bu * sadece *, Array.average 'sınırlaması nedeniyle, floatlarla çalışır. MSDN, bunu int dizisinde kullanmak için 'Array.averageBy' ile değiştirebileceğimi iddia ediyor, ancak bu farklı bir hata veriyor. Brian, bu cevabı jenerik bağlamlarda çalışmak için yeniden formüle edebilir misiniz, böylece herhangi bir aritmetik türle, sonuç çıkarsama olmaksızın çalışacak mı? –