2011-10-28 38 views
5

Tôi có một lớp DateTime và TimeSpan trong Scala (giả sử rằng các toán tử < và + hoạt động như chúng cần). Tôi đang cố gắng để xác định một chức năng 'phạm vi' mà có một thời gian bắt đầu/dừng và một khoảng thời gian cho bước. Trong C# tôi sẽ làm điều này với một năng suất, và tôi nghĩ rằng tôi sẽ có thể làm như vậy trong Scala ... ngoại trừ tôi nhận được một lỗi lạ.Bộ sưu tập trả về và có thể lặp lại sử dụng năng suất trong scala

Trên dòng 'yield t', tôi nhận được "Bắt đầu tuyên bố bất hợp pháp".

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 
    } 
    } 

Nhìn vào mã này, tôi tò mò về 2 điều: 1) Tôi đã làm gì sai? 2) mã như được viết là rất bắt buộc (sử dụng một var t, vv). Cách chức năng hơn để làm điều này trong Scala là hợp lý nhanh như thế nào?

Cảm ơn!

+0

'yield' trong Scala có gì gì để làm với 'yield' trong C# (hoặc Python). Hơn nữa, Scala không tương đương với nó - tìm kiếm nhiều câu hỏi về Scala, Python, năng suất và máy phát điện. Và, tất nhiên, tìm kiếm các câu hỏi về những gì 'yield' thực sự làm. –

+0

Tôi đã làm, và tôi đã bối rối. Câu trả lời của Debilski nói với tôi tất cả những gì tôi cần biết. – fbl

Trả lời

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

Nếu tôi có thể cung cấp cho bạn 1.000 đô la, tôi sẽ làm như vậy. Thật tuyệt vời. – fbl

0

Trong Scala, yield là một tuyên bố đặc biệt cho các vòng lặp.

Tôi không biết C#, nhưng từ những gì tôi hiểu, tôi nghĩ rằng dễ nhất cho bạn là sử dụng collection.immutable.NumericRange.Exclusive[DateTime] hoặc collection.immutable.NumericRange.Inclusive[DateTime], tùy thuộc vào khoảng thời gian của bạn là độc quyền hay bao gồm.

Để làm việc đó, bạn sẽ cần phải tạo một phiên bản Integral[DateTime] xác định loại mỹ phẩm cho loại DateTime.

+0

Vâng, 'Integral' là loại ngu ngốc để thực hiện cho' DateTime' có vẻ như. Cách tiếp cận khác với 'Iterator.iterate' là tốt hơn nhiều. –

3

Dưới đây là một phiên bản của giải pháp @Debilski với khoảng thời gian Joda:

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

def dateRange(from: DateTime, to: DateTime, step: Period): Iterator[DateTime] = 
    Iterator.iterate(from)(_.plus(step)).takeWhile(!_.isAfter(to)) 
Các vấn đề liên quan