2014-01-19 5 views
1

Машина включается и выключается. seqStartStop - seq<DateTime*DateTime>, который собирает начальное и конечное время выполнения задач машины.Работа с последовательностями с отстающими операторами

Я хотел бы создать последовательность периодов, когда машина находится в режиме ожидания. Для этого я хотел бы построить последовательность кортежей (beginIdle, endIdle).

  • beginIdle соответствует времени остановки машины во время предыдущего цикла.
  • endIdle соответствует времени начала текущего производства цикл.

На практике, я должен построить (beginIdle, endIdle), взяв второй элемент кортежа для i-1 и кулачного элемент следующего кортежа i

мне было интересно, как я мог бы получить эту задачу сделать без преобразования seqStartStop к массиву, а затем циклически перемещаясь по массиву.

Другая идея, создающая две копии seqStartStop: одна, где головка - хвост, удаляется, где головка удаляется (смещение назад элементов); а затем - map2. я мог бы использовать skip и take, как описано here

Все кажется довольно громоздким. Есть ли что-то более прямолинейное В общем, мне было интересно, как выполнять вычисления по элементам с разными лагами в последовательности.

+0

Как вы рассчитываете 'beginIdle' для первого периода и' endIdle' за последний период? –

+0

или есть еще несколько периодов простоя, чем периоды работы машины, и в этом случае нам не нужно беспокоиться об этом. –

+0

Хороший вопрос. Да, время работы устройства меньше. Периоды простоя - это периоды между рабочими периодами. Поэтому всегда существует один период простоя меньше числа рабочих периодов. – NoIdeaHowToFixThis

ответ

3

Вы можете осуществить это довольно легко с Seq.pairwise и Seq.map:

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

Что касается более общего вопроса о выполнении на последовательностей с различными периодами запаздывания, вы можете осуществить это с помощью Seq.skip и Seq.zip производить комбинированные последовательность с любым периодом ожидания, который вам требуется.

+0

Ваше решение с 'Seq.pairwise' действительно изящно. благодаря – NoIdeaHowToFixThis

1

Идея использования map2 с двумя копиями последовательности, слегка сдвинутой по хвосту исходной последовательности, является довольно стандартной в функциональном программировании, поэтому я бы рекомендовал этот маршрут.

Функция Seq.map2 прекрасно работает при работе со списками разной длины - она ​​просто останавливается, когда вы достигаете конца более короткого списка, поэтому вам не нужно нарезать последний элемент оригинальной копии.

Остерегайтесь того, как рассчитан ваш оригинал seq<DateTime*DateTime>. Он будет пересчитываться каждый раз, когда он перечисляется, поэтому с идеей map2 он будет рассчитан дважды. Если это дешево для расчета и не связано с побочными эффектами, это нормально. В противном случае сначала преобразуйте его в список с List.ofSeq.

Вы по-прежнему можете использовать Seq.map2 в списках в виде списка IEnumerable (т. Е. A seq). Не используйте List.map2, если списки не имеют одинаковой длины, хотя они более придирчивы, чем Seq.map2.

+0

Спасибо за обзор. Я думаю, что буду использовать две смещенные копии последовательности. – NoIdeaHowToFixThis

 Смежные вопросы

  • Нет связанных вопросов^_^