2011-10-28 69 views
5

我在斯卡拉有一个DateTime和TimeSpan类(假设<和+运算符正常工作)。我试图定义一个'范围'功能,它需要一个开始/停止时间和一个步进时间。在C#中,我会用yield来做到这一点,我认为我应该可以在Scala中做同样的事情......除非我遇到一个奇怪的错误。在斯卡拉使用收益返回和迭代收集

在'yield t'这一行上,我收到“非法声明的开始”。这段代码

def dateRange(from : DateTime, to : DateTime, step : TimeSpan) = 
    { 
     // not sure what the list'y way of doing this is 
    var t = from 

    while(t < to) 
    { 
     yield t; // error: illegal start of statement 
     t = t + step 
    } 
    } 

看,我很好奇两两件事: 1)我做了什么错? 2)编写的代码非常必要(使用var t等)。在Scala中执行此操作的功能更强大的方式是相当快速的?

谢谢!

+0

'yield' Scala中并没有任何关系做'在C#(或Python)yield'。此外,Scala与它没有相同之处 - 查看关于Scala,Python,yield和generator的许多问题。而且,当然,请查看有关“收益”的实际问题。 –

+0

我做了,我很困惑。 Debilski的回答告诉我所有我需要知道的。 – fbl

回答

17
def dateRange(from : DateTime, to : DateTime, step : TimeSpan): Iterator[DateTime] = 
    Iterator.iterate(from)(_ + step).takeWhile(_ <= to) 
+0

如果我能给你+1000,我会的。棒极了。 – fbl

0

在斯卡拉,yield是for循环的一个特殊语句。

我不知道C#,但根据我的理解,我认为最简单的方法是使用collection.immutable.NumericRange.Exclusive[DateTime]collection.immutable.NumericRange.Inclusive[DateTime],具体取决于您的间隔是独占还是包含。

为了达到这个目的,您需要创建一个Integral[DateTime]实例,该实例定义DateTime类型的算术。

+0

好吧,'积分'是一种愚蠢的实施'DateTime'似乎。 'Iterator.iterate'的另一种方法好得多。 –

3

这里有一个版本的@Debilski解决方案与乔达时间段:

import org.joda.time.{DateTime, Period} 

def dateRange(from: DateTime, to: DateTime, step: Period): Iterator[DateTime] = 
    Iterator.iterate(from)(_.plus(step)).takeWhile(!_.isAfter(to))