在像scala这样的函数编程语言中,停止对集合进行迭代的方法是什么?例如;如果给定中有0,则返回true



在像scala这样的函数编程语言中,停止对集合进行迭代的方法是什么?例如;如果给定值中有0,则返回true。

给定数组的大小可以是100,其中0作为第一个元素。如何在scala中使用纯FP实现这一点?

对于命令式方法,通常是if(检查终止条件(后面加一个break来停止迭代。

我是FP&scala。有人能帮忙澄清吗?

如果您查看Lists、Sets、Vectors、Maps等的API,您会看到许多实用程序,如:reducefoldfoldLeftfoldRightmap等。

大多数函数都假定您只能在遍历整个集合后返回结果。某些处理仅直到满足条件(例如.takeWhile(cond)(,或者仅取满足条件(如find(condition)(的特定示例。经常发生的情况是,你试图用一个循环做的是几个更简单的函数的组合,例如

var index = 0;
var result = 0;
// add all elements until first element bigger than 100
while (index < list.size) {
if (list(index) > 100)
break;
index++;
result += list(index);
}

可以在功能上表示为:

list.takeWhile(i => i > 100).sum

随着你学习和使用越来越多的这些方法,表达越来越复杂逻辑的能力将会提高。如果您不介意在整个集合中进行迭代,foldreduce等通常允许您随心所欲地处理数据。

然而,如果你仍然不知道如何实现某个东西,因为你必须过滤、组合并决定停止迭代以避免noop循环,你总是可以恢复到尾部递归调用:

@scala.annotation.tailrec // annotation ensured that compiler will optimize body
def myOperation(unprocessedData: List[Int], resultSoFar: Int): Int =
unprocessedData match {
case head :: tail =>
val newResult = resultSoFar + head
myOperation(tail, newResult) // to enable tailrec instead of backtracking
// you pass partial results as argument
// and compiler will rewrite it underneath
// into while with break
case Nil =>
resultSoFar                  // final result
}

TL;博士

  • 尝试使用内置函数.map.collect.filter.drop.dropWhile.take.takeWhile来构建您需要的内容
  • 如果太难,请尝试使用foldfoldLeftfoldRightreduce
  • 如果仍然很困难,请尝试使用尾部递归-这基本上是while-break的更安全版本,因此使用该版本,yo应该能够始终实现您想要的内容

您可以使用exists

有许多类型的不可变集合,它们不会从共同的祖先继承exists,但您会通过不同的方式找到它。

这样的assert(List(0,1).exists(_ == 0))

在引擎盖下就可以了:

override final def exists(p: A => Boolean): Boolean = {
var these: List[A] = this
while (!these.isEmpty) {
if (p(these.head)) return true
these = these.tail
}
false
}

assert(scala.collection.immutable.ArraySeq(0,1).exists(_ == 0))

将调用:

def exists(p: A => Boolean): Boolean = {
var res = false
val it = iterator
while (!res && it.hasNext) res = p(it.next())
res
}

相关内容

最新更新