很像这个问题:
说代码是
def findFirst[T](objects: List[T]):T = {
for (obj <- objects) {
if (expensiveFunc(obj) != null) return /*???*/ Some(obj)
}
None
}
Run Code Online (Sandbox Code Playgroud)
如何在scala中从for循环中生成单个元素?
我不想使用find,就像原始问题中提出的那样,我很好奇是否以及如何使用for循环实现它.
*更新*
首先,感谢所有评论,但我想我在问题中并不清楚.我正在为这样的事情拍摄:
val seven = for {
x <- 1 to 10
if x == 7
} return x
Run Code Online (Sandbox Code Playgroud)
那不编译.这两个错误是: - 返回外部方法定义 - 方法main有return语句; 需要结果类型
我知道在这种情况下find()会更好,我只是在学习和探索语言.在一个更复杂的情况下,有几个迭代器,我认为找到for实际上可以是有用的.
感谢评论者,我将开始赏金以弥补问题的糟糕结果:)
Phi*_*ppe 21
如果你想使用一个for回路,它采用了更好的语法比链式调用.find,.filter等等,有一个巧妙的花招.而不是迭代像列表这样的严格集合,而不是像迭代器或流这样的惰性集合.如果你从一个严格的集合开始,让它变得懒惰,例如.toIterator.
我们来看一个例子吧.
首先让我们定义一个"嘈杂"的int,它会告诉我们何时调用它
def noisyInt(i : Int) = () => { println("Getting %d!".format(i)); i }
Run Code Online (Sandbox Code Playgroud)
现在让我们填写一些列表:
val l = List(1, 2, 3, 4).map(noisyInt)
Run Code Online (Sandbox Code Playgroud)
我们想要寻找第一个均匀的元素.
val r1 = for(e <- l; val v = e() ; if v % 2 == 0) yield v
Run Code Online (Sandbox Code Playgroud)
以上行导致:
Getting 1!
Getting 2!
Getting 3!
Getting 4!
r1: List[Int] = List(2, 4)
Run Code Online (Sandbox Code Playgroud)
...意味着访问了所有元素.这是有道理的,因为结果列表包含所有偶数.让我们这次迭代一个迭代器:
val r2 = (for(e <- l.toIterator; val v = e() ; if v % 2 == 0) yield v)
Run Code Online (Sandbox Code Playgroud)
这导致:
Getting 1!
Getting 2!
r2: Iterator[Int] = non-empty iterator
Run Code Online (Sandbox Code Playgroud)
请注意,循环仅在可以确定结果是空的还是非空的迭代器时执行.
要获得第一个结果,您现在可以直接致电r2.next.
如果需要Option类型的结果,请使用:
if(r2.hasNext) Some(r2.next) else None
Run Code Online (Sandbox Code Playgroud)
编辑此编码中的第二个示例只是:
val seven = (for {
x <- (1 to 10).toIterator
if x == 7
} yield x).next
Run Code Online (Sandbox Code Playgroud)
...当然,如果您要使用,您应该确保始终至少有一个解决方案.next.或者,使用headOption,为所有Traversables 定义,以获得Option[Int].
dap*_*pek 18
您可以将列表转换为流,以便只有按需评估for循环包含的任何过滤器.但是,从流中产生的总是会返回一个流,而你想要的是我想要一个选项,因此,作为最后一步,你可以检查结果流是否至少有一个元素,并将其头部作为一个选项返回.headOption函数就是这样做的.
def findFirst[T](objects: List[T], expensiveFunc: T => Boolean): Option[T] =
(for (obj <- objects.toStream if expensiveFunc(obj)) yield obj).headOption
Run Code Online (Sandbox Code Playgroud)