2010-03-18 32 views
6

Đây là điều tôi thường gặp, nhưng tôi không biết cách làm thanh lịch. Tôi có một bộ sưu tập các đối tượng Foo. Foo có một phương thức bar() có thể trả về null hoặc một đối tượng Bar. Tôi muốn quét bộ sưu tập, gọi phương thức bar() của mỗi đối tượng và dừng lại trên phương thức đầu tiên trả về một tham chiếu thực sự và trả về tham chiếu đó từ quá trình quét.thành ngữ scala tốt nhất để tìm và trả lại

Rõ ràng:

foos.find (.! _ Bar = null) .bar

hiện các trick, nhưng kêu gọi hai lần #bar.

Trả lời

7

Bạn có thể làm điều đó với bất kỳ Iterable bằng cách sử dụng iterator (mà đánh giá một cách lười biếng - nó được gọi elements trong 2.7). Hãy thử cách này:

case class Foo(i: Int) { 
    def bar = { 
    println("Calling bar from Foo("+i+")") 
    (if ((i%4)==0) "bar says "+i else null) 
    } 
} 
val foos = List(Foo(1),Foo(2),Foo(3),Foo(4),Foo(5),Foo(6)) 
foos.iterator.map(_.bar).find(_!=null) 
+0

có sự khác biệt nào giữa điều này và sử dụng phép chiếu không? – IttayD

+0

Bản ghi nhớ luồng [T] là sự khác biệt 'val ánh xạ = foos.elements.map (_. Bar); mapped.find (_! = null); mapped.find (_! = null) 'trả về' Một số (thanh nói 4) 'và' None' trong đó 'val ánh xạ = foos.projection.map (_. bar); mapped.find (_! = null); mapped.find (_! = null) 'trả về hai lần' Một số (thanh nói 4) '. –

+0

'foos.view' trong Scala 2.8 trả về giống như' foos.projection' nhưng đánh giá các phần tử hai lần (không ghi nhớ). –

8

Làm việc trên Stream [T] trả về bởi Seq.projection là một thủ thuật rất hay

foos.projection map (_.bar) find (_.size > 0) 

này sẽ lập bản đồ các giá trị cần thiết để thực hiện tìm.

Trong Scala 2.8 đó là:

foos.view map (_.bar) find (_.size > 0) 
Các vấn đề liên quan