将Scala序列转换为一个序列的序列

3

我有一个序列,如下所示:

Seq(1,2,3) 

我正在尝试获取一个类似于这样的序列:

Sequence of a Sequence

Seq(Seq(1), Seq(1,2), Seq(1,2,3))

以下是我的翻译:

这是我想到的内容:

  def pop(acc: Seq[Seq[Int]], elems: Seq[Int]): Seq[Int] = elems match {
    case Nil => acc.flatten
    case x :: xs =>
      pop(acc ++ Seq(Seq(x, xs.head)), xs.tail)
  }

正如所料,在执行xs.head时,我遇到了NoSuchElementException异常。我确信一定是我做错了什么!也许我漏掉了什么。虽然这只是一次尝试,但结果并不如预期。
编辑:最初的目标是将作为输入的字符串“1.2.3”拆分为字符串序列Seq("1)、Seq("1.2")、Seq("1.2.3")。
为实现这个目标,我首先根据.字符进行拆分,然后遍历生成的序列,并使用.字符将它们再次合并。

5个回答

7
 Seq(1,2,3).scanLeft(Seq[Int]())(_ :+ _).tail

如果列表很长,在scanLeft中向Seq的末尾添加可能会变得太昂贵。在这种情况下,您可以将其前置到一个列表中,并添加反转步骤,或使用一些可变构建器(如ListBuffer)。

5
你也可以使用 inits 来实现这一点(虽然效率不高,但更加简洁)。
scala> Seq(1,2,3).inits.toList.reverse.tail
res0: List[Seq[Int]] = List(List(1), List(1, 2), List(1, 2, 3))

编辑: 根据问题更新,查找包含点"."分隔符的字符串的所有前缀的类似方法就是将字符串视为字符序列:

"1.2.3".inits.filter(s => s.nonEmpty && !s.endsWith(".")).toList.reverse

酷!为什么这是低效的? - joesan
1
它遍历输入两次 - 一次创建“inits”结果,一次反转它。当然,这仅对大型列表有意义,对于短列表来说,这是可以忽略不计的。 - Tzach Zohar
我觉得我喜欢这个,因为在我的Seq中,我永远不会有超过3个元素! - joesan
很高兴能够帮助!尽管我必须承认,我发现@Landei的解决方案(使用scanLeft)更加优雅,但愿我自己能想到它 :) - Tzach Zohar
您介意再看一下我的问题吗?我已经编辑过了! - joesan
显示剩余2条评论

4
val input = Seq(1,2,3)
val result = (1 to input.length).map(input.take).toList // List(List(1), List(1, 2), List(1, 2, 3))

2
+1,以及另一种相同精神的变体,使用indicesinput.indices.map(i => input.take(i + 1)) - Alexis C.

0
快要完成了:
  def pop(acc: Seq[Seq[Int]], elems: Seq[Int]): Seq[Seq[Int]] = elems match {
    case Nil => acc
    case x :: xs =>
      if (acc.isEmpty)
        pop(Seq(Seq(x)), xs)
      else
        pop(acc ++ Seq(acc.last ++ Seq(x)), xs)
  }

0
如果您的Seq没有重复项并且已排序,您可以执行以下操作:
val yourSeq = Seq(1,2,3)
yourSeq.map(e => Seq(yourSeq.takeWhile(_ <= e))).flatten

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接