在 Scala 中编写带有偏移量的通用 takeWhile
Writing generic takeWhile with an offset in Scala
我有一个 takeWhile
的用例,但我想在谓词为真后保留固定数量的项目。我还试图将其编写为尽可能通用的集合类型。所以像:
def takeWhileWithOffset[A, Iter[_] <: Iterable[A]](iter: Iter[A], p: A => Boolean, offset: Int)
我选择 Iterable
作为边界,因为希望它与 Stream
一起工作。但是我很难弄清楚如何进行这项工作。如果我使用的是严格集合,并且偏移量不是正数,我可以使用 dropRight
。但是 Iterable
没有 dropRight
.
正例比较棘手。我可以使用 sliding
有效地获取未来的项目,然后在 takeWhile
终止后使用 init
和 lastOption
。但是 Iterable
没有 init
和 lastOption
.
所以棘手的是我希望我的方法是惰性的,但要利用迭代项可以被视为严格集合这一事实——但 仅当 takeWhile
终止。有办法吗?
span
和 take
:
scala> val it = (1 to 100).iterator
it: Iterator[Int] = non-empty iterator
scala> val (a, b) = it.span(_ < 10)
a: Iterator[Int] = non-empty iterator
b: Iterator[Int] = unknown-if-empty iterator
scala> val res = a ++ b.take(5)
res: Iterator[Int] = non-empty iterator
scala> res.toList
res0: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
我有一个 takeWhile
的用例,但我想在谓词为真后保留固定数量的项目。我还试图将其编写为尽可能通用的集合类型。所以像:
def takeWhileWithOffset[A, Iter[_] <: Iterable[A]](iter: Iter[A], p: A => Boolean, offset: Int)
我选择 Iterable
作为边界,因为希望它与 Stream
一起工作。但是我很难弄清楚如何进行这项工作。如果我使用的是严格集合,并且偏移量不是正数,我可以使用 dropRight
。但是 Iterable
没有 dropRight
.
正例比较棘手。我可以使用 sliding
有效地获取未来的项目,然后在 takeWhile
终止后使用 init
和 lastOption
。但是 Iterable
没有 init
和 lastOption
.
所以棘手的是我希望我的方法是惰性的,但要利用迭代项可以被视为严格集合这一事实——但 仅当 takeWhile
终止。有办法吗?
span
和 take
:
scala> val it = (1 to 100).iterator
it: Iterator[Int] = non-empty iterator
scala> val (a, b) = it.span(_ < 10)
a: Iterator[Int] = non-empty iterator
b: Iterator[Int] = unknown-if-empty iterator
scala> val res = a ++ b.take(5)
res: Iterator[Int] = non-empty iterator
scala> res.toList
res0: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)