【问题标题】:Process sequence of elements in scalascala中元素的处理顺序
【发布时间】:2021-08-13 07:45:57
【问题描述】:

给定一个有序的pair序列,如果元素是连续的或更小的,我会组合它们,如果不是,则跳过。 例如: 如果 A = Seq((1,2),(3,4),(5,6),(8,10)(11,15))

输出应该是 Seq((1,6),(8,15))

因为当前条目的最后一个元素与下一个条目的第一个元素是连续的

如果 B = Seq((1,4),(3,5),(6,7),(9,10)(11,15))

输出应该是 Seq((1,7),(9,15))

因为当前条目的最后一个元素小于下一个条目的第一个元素

我尝试了类似的方法:

val finalOut = mySeq.sliding(2).map {
          case Array(x, y, _*) => (x, y, (x._2 - y._1))
        }.toList

这样做的问题是它一次只需要 2 个元素,而我们需要继续遍历,除非连续性存在间隙。我不确定如何在 scala 中获得它。

我也尝试实现 for 循环,但这也无济于事,因为它一次处理一个元素,并且无助于跟踪其他元素或计数器,如 c++。

【问题讨论】:

    标签: arrays scala loops sorting tuples


    【解决方案1】:

    您可以使用foldRight 执行此操作并累积到一个新的Seq

    这行得通

    val tups1 = Seq((1,2),(3,4),(5,6),(8,10),(11,15))
    val tups2 = Seq((1,4),(3,5),(6,7),(9,10),(11,15))
    
    
    def f(tups: Seq[(Int, Int)]): Seq[(Int, Int)] = {
    
      val emptySeq: Seq[(Int, Int)] = Seq()
    
      tups.foldRight(emptySeq){ (next, accum) => accum match {
        case Nil => Seq(next)
        case (a, b) +: cs if a - 1 <= next._2 => (next._1, next._2 max b) +: cs
        case _ => next +: accum 
      }}
    }
    
    f(tups1) // Seq[(Int, Int)] = List((1,6), (8,15))
    f(tups2) // Seq[(Int, Int)] = List((1,7), (9,15))
    

    我会使用 foldRight 而不是 foldLeft,因为 Seq 是底层的列表,而对于列表,前置是恒定的,而附加是 O(n),而 foldRight 让您只需要前置即可完成此操作。

    https://docs.scala-lang.org/overviews/collections/performance-characteristics.html

    【讨论】:

    • 不错的解决方案。在第二种情况下,由于next._2 可能大于b,它可能应该返回(next._1, next._2 max b) +: cs 之类的内容以涵盖Seq((1,7), (3,6), (9,10)) 之类的情况。
    • @Shrey 它是accum 上的模式匹配,这是您作为结果累积的Seq[(Int, Int)](a, b) 是头部,cs 是尾部。 next 是输入 tups 中的下一个元组,您正在从右到左迭代(通过 foldRight)。
    • @LeoC 好点。编辑答案以合并。
    • Seqs 不是Lists,它们可能是,也可能不是。如果您想要 List 使用 List 而不是 (无用的恕我直言) 接口。 - 另外,您也可以使用Seq.empty[T]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多