代码之家  ›  专栏  ›  技术社区  ›  ntviet18

使用上一个元素折叠

  •  2
  • ntviet18  · 技术社区  · 7 年前

    鉴于 val as: Seq[Int] = ...

    很多时候,我需要对两个连续的元素应用一个操作,例如。

    顺便说一下,我不喜欢

    for (i <- 1 until as.size) {
      // do something with as(i) and as(i - 1)
    }
    

    或其他人

    as.tail.foldLeft((0, as.head)) { (acc, e) =>
      // do something with acc._2 and e 
      // and try to not forget returning (_, e) 
    }
    

    如何为该场景编写更好的代码?

    3 回复  |  直到 7 年前
        1
  •  5
  •   Andrey Tyukin    7 年前

    你可以 zip 序列 as 有自己的 tail :

    for ((prev, curr) <- as zip as.tail) {
      // do something with `prev` and `curr`
    }
    

    或者你可以使用 sliding :

    for (window <- as.sliding(2)) {
      val prev = window(0)
      val curr = window(1)
      // do something with `prev` and `curr`
    }
    
        2
  •  1
  •   jwvh    7 年前

    这里有一种方法可以将序列的开头提供给后续的每个元素。

    val sq:Seq[Int] = Seq(. . .)
    
    sq.headOption.fold(sq){hd =>
      sq.tail.map(/*map() or fold() with the hd value*/)
    }
    

    请注意,这对于1或零元素的集合是安全的。

        3
  •  0
  •   Jordan Cutler    7 年前

    可以制作支持上一元素的自己的折叠。 使用1或零元素集合是安全的。

      def foldLeftWithPrevious[A, B](as: Seq[A], accumulator: B)(f: (B, A, A) => B): B = {
        @scala.annotation.tailrec
        def foldLeftInner(list2: Seq[A], previous: A, accumulator: B, f: (B, A, A) => B): B = {
          if (list2.isEmpty) accumulator
          else foldLeftInner(list2.tail, list2.head, f(accumulator, previous, list2.head), f)
        }
    
        if (as.length <= 1) accumulator
        else foldLeftInner(as.tail, as.head, accumulator, f)
      }
    

    请随意使用此代码段进行测试。

    val foldLeftTest = Seq(1)
      foldLeftWithPrevious(foldLeftTest, 0)((accum, previous, current) => {
        println("accum = " + accum)
        println("previous = " + previous)
        println("current = " + current)
        println("accum will be... " + accum + " + " + previous + " + " + current)
        println("which is... " + (accum + previous + current))
        accum + previous + current
      })
    
    推荐文章