如何在 Scala 中对可变长度的重复序列进行分组
我有一个以某种模式重复的整数集合:
val repeatingSequence = List(1,2,3,1,2,3,4,1,2,1,2,3,4,5)
我想在模式重复时将该列表分段;在本例中,当序列返回到 1 时:
val groupedBySequence = List(List(1,2,3), List(1,2,3,4), List(1,2), List(1,2,3,4,5))
请注意,当序列跳回 1 时我正在分组,但序列可以是任意长度。我和我的同事通过添加一个名为“groupWhen”的附加方法解决了这个问题。
class IteratorW[A](itr: Iterator[A]) {
def groupWhen(fn: A => Boolean): Iterator[Seq[A]] = {
val bitr = itr.buffered
new Iterator[Seq[A]] {
override def hasNext = bitr.hasNext
override def next = {
val xs = collection.mutable.ListBuffer(bitr.next)
while (bitr.hasNext && !fn(bitr.head)) xs += bitr.next
xs.toSeq
}
}
}
}
implicit def ToIteratorW[A](itr: Iterator[A]): IteratorW[A] = new IteratorW(itr)
> repeatingSequence.iterator.groupWhen(_ == 1).toSeq
List(List(1,2,3), List(1,2,3,4), List(1,2), List(1,2,3,4,5))
但是,我们都觉得集合库中潜藏着一个更优雅的解决方案。
I have a collection of ints that repeat themselves in a pattern:
val repeatingSequence = List(1,2,3,1,2,3,4,1,2,1,2,3,4,5)
I'd like to section that List up when the pattern repeats itself; in this case, when the sequence goes back to 1:
val groupedBySequence = List(List(1,2,3), List(1,2,3,4), List(1,2), List(1,2,3,4,5))
Notice that I'm grouping when the sequence jumps back to 1, but that the sequence can be of arbitrary length. My colleague and I have solved it by adding an additional method called 'groupWhen'
class IteratorW[A](itr: Iterator[A]) {
def groupWhen(fn: A => Boolean): Iterator[Seq[A]] = {
val bitr = itr.buffered
new Iterator[Seq[A]] {
override def hasNext = bitr.hasNext
override def next = {
val xs = collection.mutable.ListBuffer(bitr.next)
while (bitr.hasNext && !fn(bitr.head)) xs += bitr.next
xs.toSeq
}
}
}
}
implicit def ToIteratorW[A](itr: Iterator[A]): IteratorW[A] = new IteratorW(itr)
> repeatingSequence.iterator.groupWhen(_ == 1).toSeq
List(List(1,2,3), List(1,2,3,4), List(1,2), List(1,2,3,4,5))
However, we both feel like there's a more elegant solution lurking in the collection library.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
给定一个迭代器
itr
,这就能解决问题:Given an iterator
itr
, this will do the trick:众所周知,fold 可以做所有事情...;)
请将此视为混淆的 Scala 竞赛的条目,而不是真正的答案。
As well all know, fold can do everything... ;)
Please regard this as an entry for the obfuscated Scala contest rather than as a real answer.
这是我使用
span
提出的一个不太优雅的解决方案:Here's a not-exactly-elegant solution I bashed out using
span
: