【问题标题】:How to replace values in one Seq with values from another Seq in Scala?如何用Scala中另一个Seq的值替换一个Seq中的值?
【发布时间】:2015-04-12 06:32:04
【问题描述】:

我有序列:

val A = Seq(1,3,0,4,2,0,7,0,6)
val B = Seq(8,9,10)

我需要一个新序列,其中 0 被第二个序列中的值替换:

Seq(1,3,8,4,2,9,7,10,6)

如何在函数式风格中做到这一点?

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    您可以在此处使用map,将所有0 替换为b 的下一个元素(将b 转换为迭代器,并使用next):

    val a = Seq(1,3,0,4,2,0,7,0,6)
    val b = Seq(8,9,10).iterator
    a.map { e => if (e == 0) b.next else e } //Seq(1,3,8,4,2,9,7,10,6)
    

    【讨论】:

      【解决方案2】:

      不确定迭代器是否真正起作用。无论如何,这是一个替代方案

      val A = Seq(1,3,0,4,2,0,7,0,6)  
      val B = Seq(8,9,10)              
      A.foldLeft((B, Seq[Int]())) {case ((b, r), e) => 
                if (e == 0 && ! b.isEmpty) (b.tail, b.head +: r) else (b, e +: r) }
         ._2.reverse
      //> res0: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 10, 6)
      

      编辑:如果我们没有 B 的元素,则根据评论更新以保留零

      编辑2:

      模式匹配变体更整洁:

      A.foldLeft((B, Seq[Int]())){case ((h +: t, r), 0) =>  (t, h +: r)
                                  case ((b, r), e) => (b, e +: r)}
       ._2.reverse
      

      并且,基于what is proper monad or sequence comprehension to both map and carry state across?

      A.mapAccumLeft(B, { case ((h +: t), 0) =>  (t, h)
                          case (b, e)  => (b, e) }
      

      (可能我没有安装 scalaz 来测试它)

      【讨论】:

      • 如果零多于 B 中的元素,则保留零,如果小于 B 中的元素,则仅使用 B 中的第一个值。是的,迭代器似乎不起作用。
      • 已更新以处理 B 元素用完
      【解决方案3】:

      如果您想了解尾递归,那么这很适合您。

      @annotation.tailrec
        def f(l1: Seq[Int], l2: Seq[Int], res: Seq[Int] = Nil): Seq[Int] = {
          if (l1 == Nil) res
          else {
            if (l1.head == 0 && l2 != Nil) f(l1.tail, l2.tail, res :+ l2.head)
            else
              f(l1.tail, l2, res :+ l1.head)
          }
        }
      
      val A = Seq(1, 3, 0, 4, 2, 0, 7, 0, 6)
      val B = Seq(8, 9, 10)
      
      scala> f(A,B)
      res0: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 10, 6)
      

      如果 B 中的元素用完了,

      val A = Seq(1, 3, 0, 4, 2, 0, 7, 0, 6)
      val B = Seq(8, 9)
      scala> f(A,B)
      res1: Seq[Int] = List(1, 3, 8, 4, 2, 9, 7, 0, 6)
      

      如果 A 中的元素小于 B 则,

      val A = Seq(1, 0)
      val B = Seq(8, 9, 10)
      scala> f(A,B)
      res2: Seq[Int] = List(1, 8)
      

      【讨论】:

        猜你喜欢
        • 2020-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-12
        • 2019-11-22
        • 2015-07-15
        相关资源
        最近更新 更多