2011-08-25 25 views
9

Tôi cần xây dựng một chuỗi các đối tượng được tải từ một tài nguyên bên ngoài. Việc tải này là một hoạt động tốn kém cần phải được trì hoãn cho đến khi các đối tượng cần thiết. Sau khi bộ sưu tập được xây dựng, tôi cần một truy cập được lập chỉ mục cho các đối tượng chứa. Thư viện chuẩn Scala có cung cấp một bộ sưu tập phù hợp với trường hợp sử dụng này không? Nếu không, cách tốt nhất để thực hiện nó là gì?Lazily đánh giá loại chuỗi được lập chỉ mục

Chỉnh sửa:
Tra cứu được lập chỉ mục nên tốt hơn là hoạt động O (1).

Trả lời

9

Lạ, Miles gần đây tweeted about this. Sau đó, câu trả lời sẽ chỉ ra Needở cuối của Name.scala ở scalaz và một điểm khác với thông số kỹ thuật 'LazyParameter.

thử nghiệm nhỏ với Cần:

import scalaz._ 
import Scalaz._ 
val longOp = { var x = 0;() => {println("longOp"); x += 1; x }} 
val seq = Seq(Need(longOp()), Need(longOp())) 
val sum = seq.map(_.value).sum 
val sum = seq.map(_.value).sum 

val v = Need(longOp()) 
val s = v.map("got " + _) 
println(s.value) 
println(s.value) 

in:

longOp:() => Int = <function0> 
seq: Seq[scalaz.Name[Int]] = List(
    [email protected], [email protected]) 
longOp 
longOp 
sum: Int = 3 
sum: Int = 3 
v: scalaz.Name[Int] = [email protected] 
s: scalaz.Name[java.lang.String] = [email protected] 
longOp 
got 3 
got 3 

Vì vậy longOp chỉ được gọi một lần vào truy cập đầu tiên có giá trị.

+0

Cảm ơn rất nhiều, tôi không thể nhắc tôi đã từng xem nó trước đây. – Nicolas

+0

'Tên' dường như đang đánh giá' giá trị' trên mỗi truy cập: http://paste.pocoo.org/show/464187/. Đó là điều không mong muốn. – missingfaktor

+1

@missingfaktor, vâng - sử dụng * Cần * ẩn ở cuối tệp. – huynhjl

2

Có vẻ như bạn muốn có một Stream.

+0

Luồng là danh sách lười và truy cập được lập chỉ mục trong luồng là hoạt động 'O (n)'. Tôi muốn một cái gì đó với các đặc tính hiệu suất 'O (1)' để tra cứu dựa trên chỉ mục. – missingfaktor

+1

bạn nên thêm tính năng xem xét hiệu suất này vào câu hỏi của mình. Đó là một yếu tố quan trọng. – Nicolas

+0

@Nicolas: Đã thêm. Cảm ơn. – missingfaktor

5

Theo hiểu biết của tôi, không có gì phù hợp trong thư viện chuẩn. Một giải pháp có thể được sử dụng một loại Lazy wrapper cho các đối tượng của bạn:

class Lazy[A](operation: => A) { 
    lazy val get = operation 
} 

Và sau đó bạn có thể xây dựng Collection[Lazy[A] của bạn với bất kỳ loại tập hợp bạn muốn sử dụng.

+0

+1, Đó chính xác là những gì tôi hiện đang giải quyết. (Ngoại trừ việc 'get' của tôi là' unary_! ':-) Tôi nghĩ rằng có thể có một số thay thế tốt hơn, hoặc ở một số góc ẩn của stdlib hoặc trong Scalaz. – missingfaktor

+0

Nó có thể là một số trong scalaz, tôi không quen thuộc với nó. – Nicolas

Các vấn đề liên quan