【问题标题】:How to make a new List in Scala from previous one by calculating all intermediate value?如何通过计算所有中间值在 Scala 中创建一个新列表?
【发布时间】:2016-05-21 11:55:54
【问题描述】:

我在 Scala 中有一个 Strings 列表。我想创建一个新列表,其中每个元素都是前一个列表中的对应元素,并附加了尽可能多的\ns,在该列表元素之前累积。像这样的:

List("a\nb\nc","\nd","e") => List("a\nb\nc","\n\n\nd","\n\n\ne")

没有新的\ns 附加到第一个,2 个额外附加到第二个(因为第一个有 2 个)和三个(第一个和第二个的累积)到第三个。

我发现这个问题在某种程度上位于 foldyield 构造之间。 在 Scala 中不使用任何可变变量等实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: scala functional-programming


    【解决方案1】:

    好吧,没有人禁止你使用 List 作为弃牌的累加器并将你的状态保存在那里。我将计算 "f" 字符,因为它更易于调试:

    val lf = List("afbfc", "fd", "e")
    def count_char(s: String) = s.count(_ == 'f')
    val fold_res = lf.foldLeft((List[String](), 0)) ((acc, next_string) =>
      (("f" * acc._2 + next_string) +: acc._1,
        count_char(next_string) + acc._2))
    fold_res._1.reverse
    

    【讨论】:

      【解决方案2】:
      def doTheThing (a: List[String]): List[String] = 
        ((0,List.empty[String]) /: a) {(acc, x) =>
          (acc._1 + x.count(_ == '\n')) -> (acc._2 ++ List("\n"*acc._1 + x))
        }._2
      

      【讨论】:

        【解决方案3】:

        和其他的差不多,在两个通道中(很慢)但可能更清晰。

        // calculate the cumulative number of \n we've seen so far
        val ns = xs.scanLeft(0){(a, s) => a + s.count(e => e == 'f')}
        //> ns  : List[Int] = List(0, 2, 3)
        
        // prepend that many "f" to the elements of the original list
        val ys = (ns zip xs).map { case (l,r) => "f"*l ++ r }
        //> ys  : List[String] = List(afbfc, fffd, fffe)
        

        【讨论】:

          猜你喜欢
          • 2018-08-13
          • 2023-01-20
          • 2015-05-20
          • 2022-10-14
          • 2022-08-13
          • 2021-07-03
          • 1970-01-01
          • 2020-01-27
          • 1970-01-01
          相关资源
          最近更新 更多