Scala 如何有效地编写此函数?
假设我正在编写函数Scala 如何有效地编写此函数?,scala,collections,Scala,Collections,假设我正在编写函数foo:Seq[B]=>Boolean,如下所示: case class B(xs: Seq[Int]) def foo(bs: Seq[B]): Boolean = bs.map(_.xs.size).sum > 0 上面的实现是次优的(因为没有必要循环所有bs元素以返回true)。您将如何有效地实施foo?好吧,对于0来说,这有点琐碎: bs.exists(!_.xs.isEmpty) 执行此任务,因为一旦找到非空的xs,您就完成了 现在,假设阈值不是微不足道的
foo:Seq[B]=>Boolean
,如下所示:
case class B(xs: Seq[Int])
def foo(bs: Seq[B]): Boolean = bs.map(_.xs.size).sum > 0
上面的实现是次优的(因为没有必要循环所有
bs
元素以返回true
)。您将如何有效地实施foo
?好吧,对于0
来说,这有点琐碎:
bs.exists(!_.xs.isEmpty)
执行此任务,因为一旦找到非空的xs
,您就完成了
现在,假设阈值不是微不足道的,例如42而不是0
然后,您可以使用bs
的迭代器,使用scanleet
增量聚合值,然后检查是否存在大于零的中间结果:
def foo(bs: Seq[Int]): Boolean = bs
.iterator
.scanLeft(0)(_ + _.xs.size)
.exists(_ > 42)
嗯,对于0
来说,这有点微不足道:
bs.exists(!_.xs.isEmpty)
执行此任务,因为一旦找到非空的xs
,您就完成了
现在,假设阈值不是微不足道的,例如42而不是0
然后,您可以使用bs
的迭代器,使用scanleet
增量聚合值,然后检查是否存在大于零的中间结果:
def foo(bs: Seq[Int]): Boolean = bs
.iterator
.scanLeft(0)(_ + _.xs.size)
.exists(_ > 42)
谢谢。如果我有两层结构呢?假设我有case类A(bs:Seq[B])
并编写了foo:A=>Boolean
@Michael,你应该能够像as.iterator.flatMap(bs.iterator.scanleet(0)(+.xs.size.),exists(>thr)
,整个构造仍然会缓慢地展开,只有那些真正需要的条目。哦,美好的非常感谢。还有一个问题:如何编写一个测试来确保foo
的惰性工作?(也许我应该问一个新问题。)@Michael将方法从Int
推广到更一般的类型参数a
。使用a=()=>Int
编写一个测试,其中前几个()=>Int
确实返回的整数总和大于阈值,但随后的()=>Int
是调用时抛出错误的“陷阱”。运行该方法。如果它返回true
而没有激活任何“陷阱”,那么您可以看到该方法是懒惰的。非常感谢。如果我有两层结构呢?假设我有case类A(bs:Seq[B])
并编写了foo:A=>Boolean
@Michael,你应该能够像as.iterator.flatMap(bs.iterator.scanleet(0)(+.xs.size.),exists(>thr)
,整个构造仍然会缓慢地展开,只有那些真正需要的条目。哦,美好的非常感谢。还有一个问题:如何编写一个测试来确保foo
的惰性工作?(也许我应该问一个新问题。)@Michael将方法从Int
推广到更一般的类型参数a
。使用a=()=>Int
编写一个测试,其中前几个()=>Int
确实返回的整数总和大于阈值,但随后的()=>Int
是调用时抛出错误的“陷阱”。运行该方法。如果它返回true
而没有激活任何“陷阱”,那么您可以看到该方法是惰性的。