2014-01-19 40 views
1

機器正在打開和關閉。 seqStartStop是一個seq<DateTime*DateTime>,它收集機器任務執行的開始和結束時間。處理滯後操作員的序列

我想生成機器閒置的時間段序列。爲了做到這一點,我想建立一個元組序列(beginIdle, endIdle)

  • beginIdle期間 前一週期對應於本機的停止時間。
  • endIdle對應於當前生產週期的開始時間 週期。

在實踐中,我通過採取元組爲i-1第二個元素下面元組i

我想知道如何我能得到這個任務完成的拳頭元素打造(beginIdle, endIdle)無需轉換seqStartStop到數組,然後以一種必要的方式遍歷數組。

創建seqStartStop的兩個副本的另一個想法是:刪除頭部的尾部,刪除頭部的頭部(將元素向後移動);然後申請map2。 我可以使用skiptake如上所述here

所有這些看起來相當麻煩。有沒有更簡單的方法 一般來說,我想知道如何執行序列中不同滯後元素的計算。

+0

你將如何計算第一個時期的'beginIdle'和最後一個時期的'endIdle'? –

+0

或者是否有比機器打開期間少一個空閒週期,在這種情況下我們不需要擔心它。 –

+0

好問題。是的,機器運行時的空閒時間更短。空閒時段是工作時段之間的時段。因此,總有一個閒置期少於工作期的數量。 – NoIdeaHowToFixThis

回答

3

您可以Seq.pairwiseSeq.map很容易地實現這一點:

let idleTimes (startStopTimes : seq<DateTime * DateTime>) = 
    startStopTimes 
    |> Seq.pairwise 
    |> Seq.map (fun (_, stop) (start, _) -> 
     stop, start) 

至於與不同的滯後時間順序執行的更普遍的問題,你可以實現,通過使用Seq.skipSeq.zip以產生組合順序與您需要的任何滯後期。

+0

「Seq.pairwise」的解決方案非常流暢。謝謝 – NoIdeaHowToFixThis

1

使用map2帶有兩個序列拷貝的想法,一個通過採用原始序列的尾部而略微移動,在功能性編程中是相當標準的,所以我會推薦該路線。

Seq.map2函數適用於處理不同長度的列表 - 它只是在您到達較短列表的末尾時停止 - 因此您不需要截斷原始副本的最後一個元素。

要注意的一件事是如何計算原始的seq<DateTime*DateTime>。每次枚舉時都會重新計算,因此使用map2這個想法,它將被計算兩次。如果計算起來很便宜,並且不涉及副作用,這很好。否則,請先將其轉換爲列表List.ofSeq

您仍然可以在列表上使用Seq.map2,因爲列表爲IEnumerable(即seq)。除非列表的長度相同,否則不要使用List.map2,因爲它比Seq.map2更挑剔。

+0

感謝您的概述。我想我會使用序列的兩個移位副本。 – NoIdeaHowToFixThis