Much like this question:
Functional code for looping with early exit
Say the code is
def findFirst[T](objects: List[T]):T = {
for (obj <- objects) {
if (expensiveFunc(obj) != null) return /*???*/ Some(obj)
}
None
}
How to yield a single element from a for loop like this in scala?
I do not want to use find, as proposed in the original question, i am curious about if and how it could be implemented using the for loop.
* UPDATE *
First, thanks for all the comments, but i guess i was not clear in the question. I am shooting for something like this:
val seven = for {
x <- 1 to 10
if x == 7
} return x
And that does not compile. The two errors are:
– return outside method definition
– method main has return statement; needs result type
I know find() would be better in this case, i am just learning and exploring the language. And in a more complex case with several iterators, i think finding with for can actually be usefull.
Thanks commenters, i’ll start a bounty to make up for the bad posing of the question 🙂
If you want to use a
forloop, which uses a nicer syntax than chained invocations of.find,.filter, etc., there is a neat trick. Instead of iterating over strict collections like list, iterate over lazy ones like iterators or streams. If you’re starting with a strict collection, make it lazy with, e.g..toIterator.Let’s see an example.
First let’s define a “noisy” int, that will show us when it is invoked
Now let’s fill a list with some of these:
We want to look for the first element which is even.
The above line results in:
…meaning that all elements were accessed. That makes sense, given that the resulting list contains all even numbers. Let’s iterate over an iterator this time:
This results in:
Notice that the loop was executed only up to the point were it could figure out whether the result was an empty or non-empty iterator.
To get the first result, you can now simply call
r2.next.If you want a result of an
Optiontype, use:Edit Your second example in this encoding is just:
…of course, you should be sure that there is always at least a solution if you’re going to use
.next. Alternatively, useheadOption, defined for allTraversables, to get anOption[Int].